Nescafé Concentrated Coffee Pods Product Launch Analysis

Minghao Du, Haohua Lu, Fengyuan Tian, Jiaman Li, Xiangping Zhou

2021-12-13

if (!require(downloader)) install.packages("downloader")
downloader::source_url("https://raw.githubusercontent.com/DMinghao/Analysis_Pocketknife/main/R/import.R", downloader::sha_url("https://raw.githubusercontent.com/DMinghao/Analysis_Pocketknife/main/R/import.R"))

clear_all_()

import_init_()
import_helper_()
import_plotly_()

pkg_list <- c(
  "tidyverse", 
  "tidymodels", 
  "kernlab", 
  "pracma", 
  "stats", 
  "ggplot2", 
  "plotly", 
  "pwr", 
  "progress", 
  "doParallel", 
  "htmlwidgets", 
  "RefManageR")
load_pkgs(pkg_list)

set.seed(123)
cores <- detectCores() - 1
cluster <- makeCluster(
  cores,
  type = "PSOCK"
  )
registerDoParallel(cl = cluster)

Part 1: Research Proposal

Executive Summary / Abstract

Fengyuan Tian - 100%:

For centuries, coffee has been one of the most popular beverages around the world. It is also a valuable commodity that impacts many countries and businesses around the globe.

In general, two main groups of coffee are fresh coffee and instant coffee. When we talk about instant coffee, we can always recall a company called Nestle. Nestle is the largest multinational food and drink manufacturer measured by revenue that they generated $76.8 billion in 2020. (Spector, 2021) Nestle’s business spreads over more than 180 countries globally. The Greater China Region (Mainland China, Hong Kong, Macau, and Taiwan) is the market that generates the most profits besides Europe and North America.

Due to the pandemic and intense competition, Nescafe is seeing a savage drop in sales in the Chinese market. Therefore, as a group of analysts, we are helping Nescafe investigate the necessity of launching a new product called concentrated coffee pods to recap its sales in the Greater China Region.

We are conducting experimental research to present the most accurate result. According to the hierarchical classification of cities in China, we applied a simple random sample to evenly split 108 cities into two groups: 54 cities in the control group and 54 cities in the treatment group. Therefore, the participants are the retail stores in each city. The dependent variable in our study is the total sales of Nescafé in a fiscal year from January 2023 to January 2024. The independent variable in our research is the launch of the concentrated coffee pods. We will launch the concentrated coffee pods in the treatment group at the beginning of the experiment. And we will collect the sales data at the end of the experiment period from all samples to compare and analyze the necessity of launching the new product. We choose to conduct a two-sample t-test in this case because we would like to compare the difference of mean between the control group and the treatment group.

Statement of the Problem

Fengyuan Tian (100%):

Nowadays, coffee has become an essential beverage for working people especially. As a result, the market size of coffee is vast. According to Verified Market Research, the market size of instant coffee reached $25.09 billion in 2020 in the world. (VMR, 2021)

With the development of the times and changes in people’s needs, there are several types of instant coffee nowadays. In terms of Nestle and instant coffee, the “powdered and liquid beverages” sector is Nestle’s most important and most profitable sector. Within the sector, Nescafe is the most famous and symbolic subsidiary corporation that is famous for making soluble coffee.

Numerous newly-rising companies challenge the sales of Nescafe in China. According to the Annual Report of Nestle in 2019, the sales in the Greater China Region declined 1.3%. (Nestle Annual Review, 2019) Things got worse due to the COVID-19 pandemic in 2020. According to the Annual Report of Nestle in 2020, the sales in the Chinese market declined 13.4%. (Nestle Annual Review, 2020) Manufacturers in China invented and produced various forms of instant coffee applicable to multiple scenarios, such as “freeze-dried coffee” and “coffee drip bag.” The most recent trending instant coffee in the Chinese market is the concentrated coffee pod.

The concentrated coffee pods are a syrup-like product extracted from coffee beans and then vacuum-frozen at extremely cold temperatures. In contrast with other kinds of instant coffee, the pods are tiny and portable, so you only need a cup of water or milk, no matter if it is hot or cold, to dilute the concentrated pods.

Therefore, Nescafe is conducting experimental research to help them decide whether it should launch the concentrated coffee pods to recapture its sales and compete with these new emerging forces.

Research Questions and Hypotheses

Fengyuan Tian (100%):

The research question of this study is: “Will the launch of Nescafe concentrated coffee pods increase Nescafe’s sales in the Chinese market?”

The null hypothesis is that the launch of Nescafe concentrated coffee pods will not change Nescafe’s sales in the Chinese market. And the alternative hypothesis is that the launch of Nescafe concentrated coffee pods will change Nescafe’s sales in the Chinese market.

Address it mathematically,

\[ H_0 : \mu (Sales_{Pods}) - \mu (Sales_{No Pods}) = 0 \] \[ H_A : \mu (Sales_{Pods}) - \mu (Sales_{No Pods}) \neq 0 \]

Importance of the Study

Fengyuan Tian (34%) Minghao Du (33%) Haohua Lu (33%):

First of all, the concentrated coffee pods are a brand-new product that there is no sufficient data such as sales data to analyze. Therefore, it is necessary to conduct profound research since it has never been done before.

Secondly, the cost of failure of the product can be numerous since manufacturers have to invest money to build a new product line and to launch advertisements. Larger manufacturers usually have a higher cost of investment since they would need to produce larger quantities than other manufacturers. Unlike other small manufacturers, Nestle can spend time and money in advance to conduct the research to lower the risk and avoid investment failure.

Lastly, the return of the experiment is substantial. By conducting this research, we are able to collect a lot of the newest data in the Chinese market. Also, this experimental design can be treated as a basic template that Nestle can apply when they are considering launching new products in the future.

Literature Review

Minghao Du (50%) Haohua Lu (50%):

The purpose of this research is to find out whether promoting a new product would impact the overall sales of the company. In this specific case, we are looking for how the Chinese coffee market reacts to Nescafe’s new concentrated coffee pods. As indicated in Figure 1, the total coffee consumption in China reveals an upward trend. However, Figure 2 suggested that the coffee production in China is showing a decrease from 2018/19 to 2020/21 and the projected production for 2021/22 is expected to remain the same as 2020/21. Through the change in sales, we will be able to see the company’s performance relative to its competitors as well as its competitiveness in the market. (Baker, W. E., & Sinkula, J. M., 2005)

Coffee market in China

Different from other markets, the Chinese consumer market relies on basic cultural competence. Consumers in China have a tendency to be more attached to their previous experiences and traditions. They tend to stick to one or two brands that they trust, this is based on their past experience and they are unlikely to switch brands. (Zhang N, 2014) Based on this characteristic of the Chinese consumer market, it is more likely for the new product from Nestle Cafe to be accepted by the Chinese consumers when compared to the other coffee brands considering that Nestle Cafe entered the Chinese market relatively early and has built up their reputation among the coffee consumers in China.

Impact of the new product

As stated in the previous section, Nescafe is considering launching a new concentrated coffee pod product in the Chinese market. There exists past research that studied the relationship between launching new products and sales growth. Referring Li & Lin, 2015, it explored the relationship between sales performance and several impacting factors that are associated with imported new products. In this study, the research results demonstrated that product meaningfulness (p < .01), product superiority (p < .001), and customer familiarity (p < .001) are having positive and significant effects on new product’s sales performance.

A previous study of the consumers’ willingness to pay for coffee in China

We would also like to know how coffee consumers of China will react when there is a new product being introduced to the market. Yang et al.(2012) researched to find out whether the amount of information regarding the product would be considered as a factor when the customers are making their decision. The study implemented maximum likelihood estimation while using linear ordinary least square (OLS) regression to provide a baseline estimate for the parameters involved. Four of the coefficients (age, marry, flavor and org_known) stood out as they were measured with consistent signs and significance with “marry” and “flavor” being mostly marginal significant. Therefore, the research reflects that not all consumers are willing to pay the same amount for a fair trade coffee. Upon further classification based on the consumers’ demographic features and age, we would expect a difference in customer willingness to purchase.

Research Plan

Jiaman Li (50%) Xiangping Zhou (50%):

Population of Interest

Since the market scope of launching liquid concentrated coffee pods is in first-tier, New first-tier, second-tier, and third-tier cities. In China, cities are ranked based on their economic level of cities and reflect differences in local income level, population, infrastructure, talent pool, business opportunities, etc. Our group selects the general public at these Tier cities as our population of interest. To be specific, the general public includes: - Existing consumers of Nestlé brand and coffee products - Consumers who buy coffee products but not the Nestlé brand

Sample Selection

The margin of error = 5% Confidence level = 95%

Population Size: 119 cities

Classification n
First-tier 4
New first-tier 15
Secend-tier 30
Third-tier 70
Total 119

Sample = 54 cities

Classification Treatment Control
First-tier 1 1
New first-tier 7 7
Secend-tier 13 13
Third-tier 33 33
Total 54 54

Sample Size

Our team decided to select our samples from the representative cities in first-tier, new first-tier, second-tier, and third-tier city-list based on the hierarchical classification of cities in China. According to the data of the China Business Network, China has 4 first-tier cities, 15 New first-tier cities, 30 second-tier cities, and 70 third-tier cities in 2021, with a total of 119. By setting the confidence interval at 95%, margin error at 10%, and response distribution at 50%, we come up with a sample size with a total of 54, which include 1 city from the first-tier city, 7 cities from the new first-tier city, 13 cities from the second-tier city, and 33 cities from the third-tier city. In the details, the number of sample cities in each tier is calculated by the ratio of the total number of cities in each tier. Also, the selected cities in each tier should be representative of other cities in the same tier based on some indicators such as economic level, demographic characteristics, and the level of sophistication in products and services.

Operational Procedures

  • Step 1: Based on the hierarchical classification of cities in China, our team used simple random sampling to select cities from each tier of cities in China and formed our treatment and control groups. In detail, each group has 54 cities in total: 1 first-tier city, 7 new first-tier cities, 13 second-tier cities, and 33 third-tier cities. In the treatment city group, we will release the Nescafé Concentrated Coffee Pods for sale, and for cities in the control group, we will not launch the new product. Besides, we will keep the operation of the previous existing products in these cities.

  • Step 2: Launch Nescafé Concentrated Coffee Pods to 54 selected cities in the treatment group and put new products on the shelves of brick-and-mortar stores, including small chain convenience stores such as 7-Eleven and median and large grocery stores such as Walmart, on December 1st, 2021. Additionally, the small private stores will not carry the product and be excluded from the treatment since those stores have limited sales information that lacks standardization and has low accuracy. As a result, the data collection procedure will be complicated, and the accuracy of our study will be affected.

  • Step 3: Collect sales data from our control group and treatment group in one year based on the sale cycle of the Nescafé Concentrated Coffee Pods.

  • Step 4: Tidy sales data and turn it into business metrics that could prove the market effectiveness of the Nescafé Concentrated Coffee Pods.

  • Step 5: Compare the overall changes in sales of Nestle’s coffee business in the test and control groups.

  • Step 6: Conclude the test and come up with a recommendation of Nescafé Concentrated Coffee Pods’ launch plan.

Brief Schedule

Behavior Time Participants
Perform the experiment: Launch new products in the treatment city group January 1st, 2022 The chain stores selected for 108 cities
(54 cities each in the treatment and control groups)
End of the experiment December 31st, 2022
Collect sales data January 1st, 2023 to January 31st, 2023
Statistical Analysis of the acquired data February 1st, 2023 to February 15th, 2023

Data Collection

Our data collection will be based on shops’ sales in our control group and treatment group. Stores under the retail channel will have sales records of Nestlé coffee. We collect the store sales data of our new products in the sample cities every month from our treatment and control groups, 54 cities in each group. For further testing, we will use city-level data containing 108 observational rows. We would then compare the mean sales volume of the control and treatment cities after conducting the test. In addition, some confounding variables, such as promotional activities and coffee consumption trends, may coexist and impact our study, underestimating the impact of the newly launched Nescafé Concentrated Coffee Pods on market sales. We would randomly select cities for the control and treatment groups to minimize the effect of confounding variables.

Data Security

Since we only collect the sales volume and amount data, there is no sensitive data related to customers’ personal information, so there will be no privacy problems.

Outcomes (Dependent Variables)

Dependent Variable (Y): Total sales of Nescafé (Nestlé SA) in a fiscal period.

Treatments (Independent Variables)

Independent Variable (X): The launch of Nestlé concentrated coffee pods (Yes=1, No=0) Considering our independent variable is a dummy variable, we use a Two-sample t-test to measure the effectiveness of the launch of Nestlé concentrated coffee pods on the total sales of Nescafé, and assume the model as:

\[ Y_i = b_1X_i+b_2+u_i \]

Where Y is the total sales of Nescafé (Nestlé SA) in a fiscal period, and

\[ X = \begin{cases} 1 = Yes\\ 0 = No \end{cases} \]

If we launch the new product, which means X = 1, bring it into the model and we get: \(Y_i=b_1+b_2+u_i\), the expected value is \({E(Y}_i)=b_1+b_2\)

In contrast, if we don’t launch the new product, which means X = 0, bring it into the model and we get: \(Y_i=b_2+u_i\), the expected value is \({E(Y}_i)=b_2\)

Our null hypothesis assumes that the total sales of Nescafé with the launch of the concentrated coffee pods will be significantly different from that without the launch, and the average difference is the coefficient of X.

The category with zero value is called the base, the benchmark for comparison with other categories. The common intercept item is the intercepted item of the base class.

\(b_1\) is called differential intercept coefficient, which indicates the difference between the intercept value of the category with a value of 1 and the intercept value of the base class.

We will use a two-sample test to test whether the difference between the classification with X equal to 1 and the base class is significant.

Other Variables

Fengyuan Tian (100%):

Variables Possible Values Descriptions
Retail Price $3 per bag In this research, we must make sure that the same retail price for this product is in each store.
Packaging The appearance of the product The design and the packaging appearance are the same.
Marketing strategy Number of advertisement In this experiment, we did not propose any advertisement for the concentrated coffee pods, we needed to make sure that each store would not make any advertisement for this product.
Capacity 25 ml We need to make sure that the capacity is constant for all pods.

Statistical Analysis Plan

Haohua Lu (50%) Minghao Du (50%):

Due to the nature of which data in this study will be simulated, the team will predetermine some attribute values for sales data generation. In the analysis stage, we will perform exploratory and quantitative analysis on the simulated data. Both of which will help the team better assess the result of the experiment. They also help the team better understand the overall geometrics of response values across different parameter value combinations.

Data simulation

To generate the most realistic sales data, we decided to use the existing data regarding the count of coffee companies in different city tiers to help decide the mean of sale; as this reflects customers in given cities’ coffee demandingness, to some degree of extent. Such that, the standard deviation of sales can also be calculated from the same data set. Before generating sales data, mean and standard deviation differences between city tiers are normalized. For the baseline sales mean, the team arbitrarily chose 100, and 10 for standard deviation. In order to obtain the most representative data, we decided to run the simulation 1000 times to capture the designated sales data distribution.

Exploratory analysis

By performing exploratory analysis, we first take a glance at our data to spot the patterns if there are any. Other than that, several plots will be generated to make sure data simulated are as expected. Following that, we will also calculate statistic properties of the simulated data to make sense of the overall data geographic.

Quantitative analysis

Two sample t-tests will be performed based on the null hypothesis being that promoting a new type of coffee has no effect on Nestle’s coffee sale and the alternative hypothesis being that the new type of coffee does have some effect. We choose to perform a two-sample t-test since the predicting sales are continuous and we are aiming to compare the difference in the mean between the treatment group and the controlled group. In terms of our sample population, the controlled group and treatment groups in our study are grouped based on the level of cities. We consider focusing on the power, p-value, and effect size resulting from our test. Scenarios like significant p-value with low power and insignificant p-value with high power are not acceptable from the outcome.

Limitations and Uncertainties

Minghao Du (20%) Haohua Lu (20%) Fengyuan Tian (20%) Jiaman Li (20%) Xiangping Zhou (20%):

Sample Selection Bias

In terms of sample selection, we choose first-tier, new, first-tier, second-tier, and third-tier cities in China as our target cities, and then use stratified sampling to set our treatment and control group. But consumers in offline stores are entirely random, and there is no guarantee that they cover all of our four customer groups. Therefore, we assume the experiment process as a black box and take the randomness as part of the market.

Lack of Online Channels

Online sales account for a relatively large part of Nescafé. Still, since it is hard to set the control group online and it will be a separate experiment to test online channels, we only consider offline channels in this experiment. We will use historical sales data based on the proportion of online and offline channels to predict and supplement online sales.

Long Experiment Period

Considering the sales cycle and seasonal effect of coffee products, we set the experiment period as one year. The long period may allow the competitor to launch new products first and take the lead in the market. But we will collect and test the data each month to monitor the real-time change of sales and draw conclusions in an effective shorter period.

Accuracy of Data Collection

Sales data of offline stores usually are collected by records of the cash register and manual aggregation. There may be a human error during the process. Therefore, we can increase the frequency and reduce the time gap of collecting data to lower the risk of error and ensure data accuracy through data proofreading in different periods.

Location on the shelf

Each retail store and supermarket have their own way of arranging goods. The location of the concentrated coffee pods on the shelves is important, and it would impact the sales of this product. It is impossible to require each store and supermarket to place the pods in the same location. Therefore, the location on the shelves would cause bias.

Pandemic

The COVID-19 pandemic had a significant influence on our society. In China, they have a strict strategy dealing with the pandemic breakout. For example, whenever a city has increasing cases, the Chinese government may shut down the entire city and require every citizen to stay at home. Meanwhile, facilities such as supermarkets may close as well. Therefore, it can have a massive influence on sales.

Competitors

Many competitors make similar products of instant coffee in China. Therefore, actions from competitors such as launching new products, promotion, advertising would impact the sales of our product. Since it is impossible to control competitors, it could cause a bias.

Part 2: Simulated Studies

Minghao Du (20%) Haohua Lu (20%) Fengyuan Tian (20%) Jiaman Li (20%) Xiangping Zhou (20%):

Init perameters

The first step was to create an empty dataset. Based on our sample selection, we simulated the sales data in 108 cities, including 2 first-tier cities, 14 new first-tier cities, 26 second-tier cities, and 66 third-tier cities. The cities were evenly split into control and treatment groups. Then, we set mean and standard deviation scales for city tiers based on the number of coffee enterprises in each city. According to a report from Pintu, we calculated the average and standard deviation of coffee shop numbers in each city and then used those numbers to decide the size of the various tiers.

n <- 108

cityClass <- c(
  rep("First", 2),
  rep("New-First", 14), 
  rep("Secend", 26), 
  rep("Third", 66))

cityClassNum <- c(
  rep(0, 2),
  rep(1, 14), 
  rep(2, 26), 
  rep(3, 66))

group <- rep(c("Treatment","Control"), n/2)

emptyData <- data.frame(Group = group, City_Tier = cityClass, City_Tier_Num = cityClassNum)

t1CoffeeShops <- c(1297, 2278, 1725, 2377)
nt1CoffeeShops <- c(1867, 1253, 1327, 983, 834, 1086, 1054, 1381)
t2CoffeeShops <- c(1099, 244, 497, 556, 339, 228, 483, 325)
t3CoffeeShops <- c(146, 258, 184, 216, 127, 59, 149, 86)

t1M <- mean(t1CoffeeShops)
t1SD <- sd(t1CoffeeShops)
nt1M <- mean(nt1CoffeeShops)
nt1SD <- sd(nt1CoffeeShops)
t2M <- mean(t2CoffeeShops)
t2SD <- sd(t2CoffeeShops)
t3M <- mean(t3CoffeeShops)
t3SD <- sd(t3CoffeeShops)

# Sales mean scale for city tiers 
sales_M_factor <- c(t1M, nt1M, t2M, t3M) / t1M

# Sales SD scale for city tiers 
sales_SD_factor <- c(t1SD, nt1SD, t2SD, t3SD) / t1SD

Helper Functions

The second step was to create four simulation and evaluation functions. The first one is a function that computes a sales value based on a data frame’s mean and standard deviation. Sales are calculated using df, mean, standard deviation, sales_M_factor, and sales_SD_factor.

The second function creates plots for the data frame. This allows us to observe the trend and differences in sales between each city.

A third function calculates the average sales results from the test. For each city, we group them into “Control” or “Treatment” cities. Using the t-test result, we will set the upper and lower bounds based on the coefficient. For comparison, we list the effect, lower bound, upper bound, and p-value in the result.

The fourth function utilizes the generateSales function to generate sales data for treatment and control groups. We set the baseline as follows: mean of treatment group = 100, the standard deviation of treatment group = 10, mean of the control group is 90, the standard deviation of the control group is 5.

# function to generate sales value from mean and SD for a dataframe
generateSales <-
  function(df, 
           mean,
           sd,
           SMF = sales_M_factor,
           SSDF = sales_SD_factor) {
    out <- df %>%
      rowwise() %>%
      mutate(Sales = rnorm(1, mean = mean * SMF[City_Tier_Num + 1], sd = sd * SSDF[City_Tier_Num + 1]))
    return(out) 
  }

# function to make plots for dataframe 
plotSales <- function(df) {
  p1 <- df %>% ggplot() + 
    geom_density(aes(Sales, color = Group)) 
  p1 <- p1 %>% ggplotly()
  p2 <- df %>% ggplot() + 
    geom_density(aes(Sales, color = City_Tier)) + 
    facet_wrap(~Group)
  p2 <- p2 %>% ggplotly()
  p3 <- df %>% 
    group_by(Group, City_Tier) %>% 
    summarize(AvgSales = mean(Sales)) %>% 
    ungroup() %>% 
    ggplot() + 
    geom_col(aes(AvgSales, City_Tier, fill = Group), position = "dodge")
  p3 <- p3 %>% ggplotly()
  
  list(p1, p2, p3)
}


# function to calculate Sales mean ttest results from a dataframe 
analyzeData <- function(df) {
  tTest <-
    t.test(
      df %>% filter(Group == "Treatment") %>% select(Sales),
      df %>% filter(Group == "Control") %>% select(Sales)
    )
  the.effect <- tTest$estimate[[1]] - tTest$estimate[[2]]
  lower.bound <- tTest$conf.int[1]
  upper.bound <- tTest$conf.int[2]
  p <- tTest$p.value
  result <- list(effect = the.effect, lower_ci = lower.bound, upper_ci = upper.bound, p = p)
  
  return(result)
}

# function to use `generateSales` make sales data for treatment and control group 
simSalesDF <-
  function(DF = emptyData,
           treatM = 100,
           treatSD = 10,
           ctrlM = 90,
           ctrlSD = 5,
           SMF = sales_M_factor,
           SSDF = sales_SD_factor) {
    treatmentData <-
      DF %>% filter(Group == "Treatment") %>% generateSales(treatM, treatSD, SMF, SSDF)
    controlData <-
      DF %>% filter(Group == "Control") %>% generateSales(ctrlM, ctrlSD, SMF, SSDF)
    
    sim.data <- treatmentData %>% rbind(controlData) %>% ungroup()
    
    return(sim.data)
  }

Explore simulated data

Single Simulation

We finalized the simulated data and plotted the data to make sure all functions worked.

# make sure all function works 

sim.data <- simSalesDF(emptyData, 110, 10, 100, 10, sales_M_factor, sales_SD_factor)

sim.data
plots <- plotSales(sim.data)

plots[[1]]
plots[[2]]
plots[[3]]
analyzeData(sim.data)
$effect
[1] 2.375294

$lower_ci
[1] -6.437825

$upper_ci
[1] 11.18841

$p
[1] 0.5941893

Finally, we constructed a power t-test to test the ideal effect size. Assume the power of the test is 0.9, according to the test result, the effect size should be 62. But due to the limitation of the size of cities, we are not able to reach the ideal sample size. But the result can provide us a reference for further analysis.

pwrTest <- pwr.t.test(n = n/2, power = 0.9)
pwrTest

     Two-sample t test power calculation 

              n = 54
              d = 0.629583
      sig.level = 0.05
          power = 0.9
    alternative = two.sided

NOTE: n is number in *each* group

Single Experiment

For experiment, we first set the number of simulation = 1000, mean of the control group = 100, standard deviation of the control group = 10, effect size = 55, significance level = 0.05. Then we run the simulation based on these parameters. Using the t-test, we got the result of the simulation: The Power of the test with an effective size of 55 and a significant level of 0.05 is 0.796.

# Number of simulations 
B <- 1000 

Experiment <- 1:B 

DFList <- c()

ctrlMean <- 100
stdDiv <- 10
effectSize <- 55
sigLevel <- 0.05

# run simulations
pb <- progress_bar$new(total = B)
for (i in Experiment) {
  pb$tick()
  DFList[[i]] <-
    emptyData %>% simSalesDF(ctrlMean + effectSize,
                             stdDiv,
                             ctrlMean,
                             stdDiv,
                             sales_M_factor,
                             sales_SD_factor)
}

expSimData <- tibble(Experiment = Experiment, DF = DFList)

# get t-test result for simulation 
simDataAnalyzed <- expSimData %>% mutate(Result = map(DF, analyzeData)) %>% unnest_wider(Result)

print(paste("Power with an effective size of ", effectSize, " and a significant level of ", sigLevel," : ", mean(simDataAnalyzed$p < sigLevel)))
[1] "Power with an effective size of  55  and a significant level of  0.05  :  0.796"
print(paste("Average P-value",mean(simDataAnalyzed$p)))
[1] "Average P-value 0.0401944253521146"
summary(simDataAnalyzed$effect)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  9.211  11.015  11.491  11.510  12.009  14.348 
summary(simDataAnalyzed$lower_ci)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
-2.0853  0.1178  0.6241  0.6195  1.1312  3.0511 
summary(simDataAnalyzed$upper_ci)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  19.67   21.87   22.40   22.40   22.94   25.64 

Experiments for different effective size

Next, we defined the effective size range to be tested as [30, 70]. For each effective size, we run an experiment of 1000 simulations to determine the power. We also got the effective size threshold given a significant level.

# define effective size range to be tested
eSize <- seq(30, 70)

# for each effective size run one experiment of 1000 simulations to determine the power
result <-
  foreach(x = eSize,
          .combine = rbind,
          .packages = c("tidyverse")) %dopar% {
            B <- 1000

            Experiment <- 1:B

            DFList <- c()

            ctrlMean <- 100
            stdDiv <- 10
            effectSize <- x
            sigLevel <- 0.05

            for (i in Experiment) {
              DFList[[i]] <-
                emptyData %>% simSalesDF(ctrlMean + effectSize,
                                         stdDiv,
                                         ctrlMean,
                                         stdDiv,
                                         sales_M_factor,
                                         sales_SD_factor)
            }

            expSimData <- tibble(Experiment = Experiment, DF = DFList)

            simDataAnalyzed <-
              expSimData %>% mutate(Result = map(DF, analyzeData)) %>% unnest_wider(Result)
            eP <- mean(simDataAnalyzed$p < sigLevel)
            eAp <- mean(simDataAnalyzed$p)
            eF <- mean(simDataAnalyzed$effect)
            eU <- mean(simDataAnalyzed$upper_ci)
            eL <- mean(simDataAnalyzed$lower_ci)

            c(x, eAp, eP, eF, eL, eU)
          }

effectPower <- as.data.frame(result) %>% as_tibble()

colnames(effectPower) <- c("eSize", "eAvgP", "ePow", "eEfs", "eLow", "eUp")

# given a significant level see the effective size threshold
effectPower <- effectPower %>% mutate(passed = ifelse(ePow < (1-sigLevel), F, T))

effectPower

To evaluate the power of the test, we built a plot to show the experiment power based on different effect sizes. We set a baseline of power as 0.95. The plot shows that when the effect size is over 60, the power test would surpass the baseline, which means that at this level, the probability of our result is larger than 95%.

# plot effective size vs experiment power
fig <- effectPower %>% ggplot() +
  geom_point(aes(eSize, ePow)) +
  geom_hline(aes(yintercept = 1 - sigLevel))

fig %>% ggplotly()

Further, we plotted the trend of p-value with the change of effect size. As shown in the graph, when the effect size is larger than 60, the average p-value reduces to less than 0.05. A p-value less than 0.05 is statistically significant. It indicates strong evidence against the null hypothesis, as there is less than a 5% probability the null is correct.

# plot Avg P vs experiment power
fig <- effectPower %>% ggplot() +
  geom_point(aes(eSize, eAvgP)) +
  geom_hline(aes(yintercept = sigLevel))

fig %>% ggplotly()

Fancy Plots

#Graph Resolution (more important for more complex shapes)
graph_reso <- 0.01

#Setup Axis
axis_x <- seq(min(effectPower$eAvgP), max(effectPower$eAvgP), by = graph_reso)
axis_y <- seq(min(effectPower$ePow), max(effectPower$ePow), by = graph_reso)

set.seed(123)
regModel <- svm_rbf(cost = 0.5, rbf_sigma = 0.8, margin = 0.01) %>%
  set_engine("kernlab") %>%
  set_mode("regression") %>%
  fit(eSize ~ eAvgP + ePow, data = effectPower)

#Sample points
xy <- meshgrid(x = axis_x, y = axis_y)
xx <- xy$X
yy <- xy$Y
dim_val <- dim(xx)
xx1 <- matrix(xx, length(xx), 1)
yy1 <- matrix(yy, length(yy), 1)
final <- cbind(xx1, yy1)
pred <- regModel %>% predict(final)

pred <- pred$.pred
pred <- matrix(pred, dim_val[1], dim_val[2])

# 3D plot for Average P vs effective size CI vs Power
effectPower %>%
  plot_ly(
    x = ~ eAvgP,
    y = ~ ePow,
    z = ~ eSize
  ) %>%
  add_markers() %>%
  add_surface(x = axis_x,
              y = axis_y,
              z = pred,
              type = 'mesh3d') %>%
  make_it_spin()
#Graph Resolution (more important for more complex shapes)
graph_reso <- 0.01

#Setup Axis
axis_x <- seq(min(effectPower$eUp), max(effectPower$eUp), by = graph_reso)
axis_y <- seq(min(effectPower$eLow), max(effectPower$eLow), by = graph_reso)

set.seed(123)
regModel <- svm_rbf(cost = 0.25, rbf_sigma = 0.2) %>%
  set_engine("kernlab") %>%
  set_mode("regression") %>%
  fit(ePow ~ eUp + eLow, data = effectPower)

#Sample points
xy <- meshgrid(x = axis_x, y = axis_y)
xx <- xy$X
yy <- xy$Y
dim_val <- dim(xx)
xx1 <- matrix(xx, length(xx), 1)
yy1 <- matrix(yy, length(yy), 1)
final <- cbind(xx1, yy1)
pred <- regModel %>% predict(final)

pred <- pred$.pred
pred <- matrix(pred, dim_val[1], dim_val[2])

# 3D plot for lower CI vs upper CI vs Power
effectPower %>%
  plot_ly(
    x = ~ eUp,
    y = ~ eLow,
    z = ~ ePow,
    text = ~ paste('Effect Size: ', eSize)
  ) %>%
  add_markers() %>%
  add_surface(x = axis_x,
              y = axis_y,
              z = pred,
              type = 'mesh3d') %>%
  make_it_spin()

Research Question 1:

Scenario 1: No Effect

Minghao Du (20%) Haohua Lu (20%) Fengyuan Tian (20%) Jiaman Li (20%) Xiangping Zhou (20%):

Will the launch of Nescafe concentrated coffee pods increase Nescafe’s sales in the Chinese market?

Simulation
# Number of simulations
B <- 1000

Experiment <- 1:B

DFList <- c()

ctrlMean <- 100
stdDiv <- 10
effectSize <- 40
sigLevel <- 0.05

# run simulations
pb <- progress_bar$new(total = B)
for (i in Experiment) {
  pb$tick()
  DFList[[i]] <-
    emptyData %>% simSalesDF(ctrlMean + effectSize,
                             stdDiv,
                             ctrlMean,
                             stdDiv,
                             sales_M_factor,
                             sales_SD_factor)
}

expSimData <- tibble(Experiment = Experiment, DF = DFList)
Analysis
# get t-test result for simulation
simDataAnalyzed <- expSimData %>% mutate(Result = map(DF, analyzeData)) %>% unnest_wider(Result)

print(paste("Power with an effective size of ", effectSize, " and a significant level of ", sigLevel," : ", mean(simDataAnalyzed$p < sigLevel)))
[1] "Power with an effective size of  40  and a significant level of  0.05  :  0.009"
print(paste("Average P value: ", mean(simDataAnalyzed$p)))
[1] "Average P value:  0.108619148251826"
summary(simDataAnalyzed$effect)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  6.075   7.880   8.357   8.375   8.874  11.213 
summary(simDataAnalyzed$lower_ci)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
-4.5231 -2.3015 -1.7816 -1.7890 -1.2757  0.6633 
summary(simDataAnalyzed$upper_ci)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  15.84   18.02   18.54   18.54   19.08   21.76 

The simulation result shows a P-value (0.1086) that is larger than 5%, which is not statistically significant. Therefore, we will accept our null hypothesis that the launch of Nescafe concentrated coffee pods will not increase Nescafe’s sales in the Chinese market. We reject our alternative hypothesis that the launch of Nescafe concentrated coffee pods will increase Nescafe’s sales in the Chinese market. In this scenario, we recommend not launching the Nescafe concentrated coffee pods in the Chinese market since it will not increase Nescafe’s sales.

Scenario 2: An Expected Effect

Minghao Du (20%) Haohua Lu (20%) Fengyuan Tian (20%) Jiaman Li (20%) Xiangping Zhou (20%):

Simulation
# Number of simulations
B <- 1000

Experiment <- 1:B

DFList <- c()

ctrlMean <- 100
stdDiv <- 10
effectSize <- 60
sigLevel <- 0.05

# run simulations
pb <- progress_bar$new(total = B)
for (i in Experiment) {
  pb$tick()
  DFList[[i]] <-
    emptyData %>% simSalesDF(ctrlMean + effectSize,
                             stdDiv,
                             ctrlMean,
                             stdDiv,
                             sales_M_factor,
                             sales_SD_factor)
}

expSimData <- tibble(Experiment = Experiment, DF = DFList)
Analysis
# get t-test result for simulation
simDataAnalyzed <- expSimData %>% mutate(Result = map(DF, analyzeData)) %>% unnest_wider(Result)

print(paste("Power with an effective size of ", effectSize, " and a significant level of ", sigLevel," : ", mean(simDataAnalyzed$p < sigLevel)))
[1] "Power with an effective size of  60  and a significant level of  0.05  :  0.961"
print(paste("Average P value: ", mean(simDataAnalyzed$p)))
[1] "Average P value:  0.0292112787561584"
summary(simDataAnalyzed$effect)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  10.03   12.02   12.50   12.53   13.09   14.67 
summary(simDataAnalyzed$lower_ci)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
-1.0695  0.8699  1.3882  1.3956  1.9509  3.5208 
summary(simDataAnalyzed$upper_ci)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  21.13   23.10   23.67   23.67   24.26   26.09 

The simulation result shows a P-value (0.0292) that is less than 5%, which is statistically significant. Therefore, we will reject our null hypothesis that the launch of Nescafe concentrated coffee pods will not increase Nescafe’s sales in the Chinese market. We accept our alternative hypothesis that the launch of Nescafe concentrated coffee pods will increase Nescafe’s sales in the Chinese market. In this scenario, we will recommend launching the Nescafe concentrated coffee pods in the Chinese market since it will increase Nescafe’s sales.

Appendix

Figure 1

Figure 1: Total coffee consumption volume in China. (USDA Foreign Agricultural Service, June 21, 2020)

Figure 2

Figure 2: Total coffee production volume in China. (USDA Foreign Agricultural Service, June 21, 2020)

References

Minghao Du (50%) Haohua Lu (50%):

ReadBib("my-paper.bib", check = FALSE) 
[1] W. E. Baker and J. M. Sinkula. "Environmental marketing strategy
and firm performance: Effects on new product performance and market
share". In: _Journal of the academy of marketing science_ 33.4 (2005),
pp. 461-475.

[2] P. by C. Textor and J. 9. "China: coffee production 2016-2022". In:
_Statista_ (Jul. 2021). <URL:
https://www.statista.com/statistics/1046603/china-coffee-production-volume/>.

[3] C. Li and C. Lin. "New product adoption and sales performance from
the importer perspective". In: _Industrial Marketing Management_ 44
(2015), pp. 98-106.

[4] Y. Ma. "China: coffee consumption 2016-2022". In: _Statista_ (Jul.
2021). <URL:
https://www.statista.com/statistics/1046674/china-coffee-consumption-volume/>.

[5] Nestle Global. "Nestle's 2019 Annual Report". In: _Nestle Global_
(2019). <URL: https://www.nestle.com/investors/annual-report>.

[6] Nestle Global. "Nestle's 2020 Annual Report". In: _Nestle Global_
(2020). <URL: https://www.nestle.com/investors/annual-report>.

[7] N. Spector. "The 10 Food and Beverage Companies Making the Most
Money". In: _GOBankingRates_ (May. 2021). <URL:
https://www.gobankingrates.com/money/business/10-food-beverage-companies-making-most-money/>.

[8] K. Wu. "China Retail Trends: Grocery in Lower-Tier Markets -Hanshow
- The World Quality Proven Electronic Shelf Labels". In: _hanshow_
(2014). <URL: https://www.hanshow.com/news/186.html>.

[9] S. Yang, W. Hu, M. Mupandawana, et al. "Consumer willingness to pay
for fair trade coffee: a Chinese case study". In: _Journal of
Agricultural and Applied Economics_ 44.1 (2012), pp. 21-34.

[10] N. Zhang and others. "Coffee market in China: trends & consumer
strategies. A coffee industry market research of a traditional
tea-drinking country". In: _Universitat Politècnica de València_
(2014).
stopImplicitCluster()
LS0tDQp0aXRsZTogIk5lc2NhZsOpIENvbmNlbnRyYXRlZCBDb2ZmZWUgUG9kcyBQcm9kdWN0IExhdW5jaCBBbmFseXNpcyINCmF1dGhvcjogIk1pbmdoYW8gRHUsIEhhb2h1YSBMdSwgRmVuZ3l1YW4gVGlhbiwgSmlhbWFuIExpLCBYaWFuZ3BpbmcgWmhvdSINCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCm91dHB1dDoNCiAgcm1kZm9ybWF0czo6ZG93bmN1dGU6IA0KICAgIHNlbGZfY29udGFpbmVkOiB0cnVlDQogICAgdGh1bWJuYWlsczogZmFsc2UNCiAgICBkZl9wcmludDogcGFnZWQNCiAgICBsaWdodGJveDogdHJ1ZQ0KICAgIGdhbGxlcnk6IHRydWUNCiAgICBlbWJlZF9mb250czogdHJ1ZQ0KICAgIGRlZmF1bHRfc3R5bGU6ICJkYXJrIg0KICAgIHRvY19kZXB0aDogNA0KICAgIGhpZ2hsaWdodDogdGFuZ28NCiAgICBjb2RlX2ZvbGRpbmc6ICJzaG93Ig0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCi0tLQ0KDQpgYGB7Y3NzIGVjaG89RkFMU0V9DQpAaW1wb3J0IHVybCgnaHR0cHM6Ly9mb250cy5nb29nbGVhcGlzLmNvbS9jc3MyP2ZhbWlseT1GaXJhK0NvZGU6d2dodEAzMDA7NDAwOzUwMDs2MDA7NzAwJmRpc3BsYXk9c3dhcCcpOw0KY29kZXsNCiAgZm9udC1mYW1pbHk6ICdGaXJhIENvZGUnIWltcG9ydGFudDsNCn0NCmBgYA0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgY29tbWVudD0iIiwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UsIHRpZHkub3B0cz1saXN0KHdpZHRoLmN1dG9mZj01NSksIHRpZHkgPSBUUlVFKQ0KYGBgDQoNCmBgYHtyIGluaXRfZW52fSANCmlmICghcmVxdWlyZShkb3dubG9hZGVyKSkgaW5zdGFsbC5wYWNrYWdlcygiZG93bmxvYWRlciIpDQpkb3dubG9hZGVyOjpzb3VyY2VfdXJsKCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vRE1pbmdoYW8vQW5hbHlzaXNfUG9ja2V0a25pZmUvbWFpbi9SL2ltcG9ydC5SIiwgZG93bmxvYWRlcjo6c2hhX3VybCgiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL0RNaW5naGFvL0FuYWx5c2lzX1BvY2tldGtuaWZlL21haW4vUi9pbXBvcnQuUiIpKQ0KDQpjbGVhcl9hbGxfKCkNCg0KaW1wb3J0X2luaXRfKCkNCmltcG9ydF9oZWxwZXJfKCkNCmltcG9ydF9wbG90bHlfKCkNCg0KcGtnX2xpc3QgPC0gYygNCiAgInRpZHl2ZXJzZSIsIA0KICAidGlkeW1vZGVscyIsIA0KICAia2VybmxhYiIsIA0KICAicHJhY21hIiwgDQogICJzdGF0cyIsIA0KICAiZ2dwbG90MiIsIA0KICAicGxvdGx5IiwgDQogICJwd3IiLCANCiAgInByb2dyZXNzIiwgDQogICJkb1BhcmFsbGVsIiwgDQogICJodG1sd2lkZ2V0cyIsIA0KICAiUmVmTWFuYWdlUiIpDQpsb2FkX3BrZ3MocGtnX2xpc3QpDQoNCnNldC5zZWVkKDEyMykNCmNvcmVzIDwtIGRldGVjdENvcmVzKCkgLSAxDQpjbHVzdGVyIDwtIG1ha2VDbHVzdGVyKA0KICBjb3JlcywNCiAgdHlwZSA9ICJQU09DSyINCiAgKQ0KcmVnaXN0ZXJEb1BhcmFsbGVsKGNsID0gY2x1c3RlcikNCmBgYA0KDQojIyBQYXJ0IDE6ICBSZXNlYXJjaCBQcm9wb3NhbA0KDQojIyMgRXhlY3V0aXZlIFN1bW1hcnkgLyBBYnN0cmFjdA0KDQoqKkZlbmd5dWFuIFRpYW4gLSAxMDAlKio6IA0KDQpGb3IgY2VudHVyaWVzLCBjb2ZmZWUgaGFzIGJlZW4gb25lIG9mIHRoZSBtb3N0IHBvcHVsYXIgYmV2ZXJhZ2VzIGFyb3VuZCB0aGUgd29ybGQuIEl0IGlzIGFsc28gYSB2YWx1YWJsZSBjb21tb2RpdHkgdGhhdCBpbXBhY3RzIG1hbnkgY291bnRyaWVzIGFuZCBidXNpbmVzc2VzIGFyb3VuZCB0aGUgZ2xvYmUuIA0KDQpJbiBnZW5lcmFsLCB0d28gbWFpbiBncm91cHMgb2YgY29mZmVlIGFyZSBmcmVzaCBjb2ZmZWUgYW5kIGluc3RhbnQgY29mZmVlLiBXaGVuIHdlIHRhbGsgYWJvdXQgaW5zdGFudCBjb2ZmZWUsIHdlIGNhbiBhbHdheXMgcmVjYWxsIGEgY29tcGFueSBjYWxsZWQgTmVzdGxlLiBOZXN0bGUgaXMgdGhlIGxhcmdlc3QgbXVsdGluYXRpb25hbCBmb29kIGFuZCBkcmluayBtYW51ZmFjdHVyZXIgbWVhc3VyZWQgYnkgcmV2ZW51ZSB0aGF0IHRoZXkgZ2VuZXJhdGVkICQ3Ni44IGJpbGxpb24gaW4gMjAyMC4gKFNwZWN0b3IsIDIwMjEpIE5lc3RsZSdzIGJ1c2luZXNzIHNwcmVhZHMgb3ZlciBtb3JlIHRoYW4gMTgwIGNvdW50cmllcyBnbG9iYWxseS4gVGhlIEdyZWF0ZXIgQ2hpbmEgUmVnaW9uIChNYWlubGFuZCBDaGluYSwgSG9uZyBLb25nLCBNYWNhdSwgYW5kIFRhaXdhbikgaXMgdGhlIG1hcmtldCB0aGF0IGdlbmVyYXRlcyB0aGUgbW9zdCBwcm9maXRzIGJlc2lkZXMgRXVyb3BlIGFuZCBOb3J0aCBBbWVyaWNhLiANCg0KRHVlIHRvIHRoZSBwYW5kZW1pYyBhbmQgaW50ZW5zZSBjb21wZXRpdGlvbiwgTmVzY2FmZSBpcyBzZWVpbmcgYSBzYXZhZ2UgZHJvcCBpbiBzYWxlcyBpbiB0aGUgQ2hpbmVzZSBtYXJrZXQuIFRoZXJlZm9yZSwgYXMgYSBncm91cCBvZiBhbmFseXN0cywgd2UgYXJlIGhlbHBpbmcgTmVzY2FmZSBpbnZlc3RpZ2F0ZSB0aGUgbmVjZXNzaXR5IG9mIGxhdW5jaGluZyBhIG5ldyBwcm9kdWN0IGNhbGxlZCBjb25jZW50cmF0ZWQgY29mZmVlIHBvZHMgdG8gcmVjYXAgaXRzIHNhbGVzIGluIHRoZSBHcmVhdGVyIENoaW5hIFJlZ2lvbi4NCg0KV2UgYXJlIGNvbmR1Y3RpbmcgZXhwZXJpbWVudGFsIHJlc2VhcmNoIHRvIHByZXNlbnQgdGhlIG1vc3QgYWNjdXJhdGUgcmVzdWx0LiBBY2NvcmRpbmcgdG8gdGhlIGhpZXJhcmNoaWNhbCBjbGFzc2lmaWNhdGlvbiBvZiBjaXRpZXMgaW4gQ2hpbmEsIHdlIGFwcGxpZWQgYSBzaW1wbGUgcmFuZG9tIHNhbXBsZSB0byBldmVubHkgc3BsaXQgMTA4IGNpdGllcyBpbnRvIHR3byBncm91cHM6IDU0IGNpdGllcyBpbiB0aGUgY29udHJvbCBncm91cCBhbmQgNTQgY2l0aWVzIGluIHRoZSB0cmVhdG1lbnQgZ3JvdXAuIFRoZXJlZm9yZSwgdGhlIHBhcnRpY2lwYW50cyBhcmUgdGhlIHJldGFpbCBzdG9yZXMgaW4gZWFjaCBjaXR5LiBUaGUgZGVwZW5kZW50IHZhcmlhYmxlIGluIG91ciBzdHVkeSBpcyB0aGUgdG90YWwgc2FsZXMgb2YgTmVzY2Fmw6kgaW4gYSBmaXNjYWwgeWVhciBmcm9tIEphbnVhcnkgMjAyMyB0byBKYW51YXJ5IDIwMjQuIFRoZSBpbmRlcGVuZGVudCB2YXJpYWJsZSBpbiBvdXIgcmVzZWFyY2ggaXMgdGhlIGxhdW5jaCBvZiB0aGUgY29uY2VudHJhdGVkIGNvZmZlZSBwb2RzLiBXZSB3aWxsIGxhdW5jaCB0aGUgY29uY2VudHJhdGVkIGNvZmZlZSBwb2RzIGluIHRoZSB0cmVhdG1lbnQgZ3JvdXAgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgZXhwZXJpbWVudC4gQW5kIHdlIHdpbGwgY29sbGVjdCB0aGUgc2FsZXMgZGF0YSBhdCB0aGUgZW5kIG9mIHRoZSBleHBlcmltZW50IHBlcmlvZCBmcm9tIGFsbCBzYW1wbGVzIHRvIGNvbXBhcmUgYW5kIGFuYWx5emUgdGhlIG5lY2Vzc2l0eSBvZiBsYXVuY2hpbmcgdGhlIG5ldyBwcm9kdWN0LiBXZSBjaG9vc2UgdG8gY29uZHVjdCBhIHR3by1zYW1wbGUgdC10ZXN0IGluIHRoaXMgY2FzZSBiZWNhdXNlIHdlIHdvdWxkIGxpa2UgdG8gY29tcGFyZSB0aGUgZGlmZmVyZW5jZSBvZiBtZWFuIGJldHdlZW4gdGhlIGNvbnRyb2wgZ3JvdXAgYW5kIHRoZSB0cmVhdG1lbnQgZ3JvdXAuIA0KDQoNCg0KIyMjIFN0YXRlbWVudCBvZiB0aGUgUHJvYmxlbQ0KDQoqKkZlbmd5dWFuIFRpYW4gKDEwMCUpKio6IA0KDQpOb3dhZGF5cywgY29mZmVlIGhhcyBiZWNvbWUgYW4gZXNzZW50aWFsIGJldmVyYWdlIGZvciB3b3JraW5nIHBlb3BsZSBlc3BlY2lhbGx5LiBBcyBhIHJlc3VsdCwgdGhlIG1hcmtldCBzaXplIG9mIGNvZmZlZSBpcyB2YXN0LiBBY2NvcmRpbmcgdG8gVmVyaWZpZWQgTWFya2V0IFJlc2VhcmNoLCB0aGUgbWFya2V0IHNpemUgb2YgaW5zdGFudCBjb2ZmZWUgcmVhY2hlZCAkMjUuMDkgYmlsbGlvbiBpbiAyMDIwIGluIHRoZSB3b3JsZC4gKFZNUiwgMjAyMSkNCg0KV2l0aCB0aGUgZGV2ZWxvcG1lbnQgb2YgdGhlIHRpbWVzIGFuZCBjaGFuZ2VzIGluIHBlb3BsZSdzIG5lZWRzLCB0aGVyZSBhcmUgc2V2ZXJhbCB0eXBlcyBvZiBpbnN0YW50IGNvZmZlZSBub3dhZGF5cy4gSW4gdGVybXMgb2YgTmVzdGxlIGFuZCBpbnN0YW50IGNvZmZlZSwgdGhlICJwb3dkZXJlZCBhbmQgbGlxdWlkIGJldmVyYWdlcyIgc2VjdG9yIGlzIE5lc3RsZSdzIG1vc3QgaW1wb3J0YW50IGFuZCBtb3N0IHByb2ZpdGFibGUgc2VjdG9yLiBXaXRoaW4gdGhlIHNlY3RvciwgTmVzY2FmZSBpcyB0aGUgbW9zdCBmYW1vdXMgYW5kIHN5bWJvbGljIHN1YnNpZGlhcnkgY29ycG9yYXRpb24gdGhhdCBpcyBmYW1vdXMgZm9yIG1ha2luZyBzb2x1YmxlIGNvZmZlZS4NCg0KTnVtZXJvdXMgbmV3bHktcmlzaW5nIGNvbXBhbmllcyBjaGFsbGVuZ2UgdGhlIHNhbGVzIG9mIE5lc2NhZmUgaW4gQ2hpbmEuIEFjY29yZGluZyB0byB0aGUgQW5udWFsIFJlcG9ydCBvZiBOZXN0bGUgaW4gMjAxOSwgdGhlIHNhbGVzIGluIHRoZSBHcmVhdGVyIENoaW5hIFJlZ2lvbiBkZWNsaW5lZCAxLjMlLiAoTmVzdGxlIEFubnVhbCBSZXZpZXcsIDIwMTkpIFRoaW5ncyBnb3Qgd29yc2UgZHVlIHRvIHRoZSBDT1ZJRC0xOSBwYW5kZW1pYyBpbiAyMDIwLiBBY2NvcmRpbmcgdG8gdGhlIEFubnVhbCBSZXBvcnQgb2YgTmVzdGxlIGluIDIwMjAsIHRoZSBzYWxlcyBpbiB0aGUgQ2hpbmVzZSBtYXJrZXQgZGVjbGluZWQgMTMuNCUuIChOZXN0bGUgQW5udWFsIFJldmlldywgMjAyMCkgTWFudWZhY3R1cmVycyBpbiBDaGluYSBpbnZlbnRlZCBhbmQgcHJvZHVjZWQgdmFyaW91cyBmb3JtcyBvZiBpbnN0YW50IGNvZmZlZSBhcHBsaWNhYmxlIHRvIG11bHRpcGxlIHNjZW5hcmlvcywgc3VjaCBhcyAiZnJlZXplLWRyaWVkIGNvZmZlZSIgYW5kICJjb2ZmZWUgZHJpcCBiYWcuIiBUaGUgbW9zdCByZWNlbnQgdHJlbmRpbmcgaW5zdGFudCBjb2ZmZWUgaW4gdGhlIENoaW5lc2UgbWFya2V0IGlzIHRoZSBjb25jZW50cmF0ZWQgY29mZmVlIHBvZC4NCg0KVGhlIGNvbmNlbnRyYXRlZCBjb2ZmZWUgcG9kcyBhcmUgYSBzeXJ1cC1saWtlIHByb2R1Y3QgZXh0cmFjdGVkIGZyb20gY29mZmVlIGJlYW5zIGFuZCB0aGVuIHZhY3V1bS1mcm96ZW4gYXQgZXh0cmVtZWx5IGNvbGQgdGVtcGVyYXR1cmVzLiBJbiBjb250cmFzdCB3aXRoIG90aGVyIGtpbmRzIG9mIGluc3RhbnQgY29mZmVlLCB0aGUgcG9kcyBhcmUgdGlueSBhbmQgcG9ydGFibGUsIHNvIHlvdSBvbmx5IG5lZWQgYSBjdXAgb2Ygd2F0ZXIgb3IgbWlsaywgbm8gbWF0dGVyIGlmIGl0IGlzIGhvdCBvciBjb2xkLCB0byBkaWx1dGUgdGhlIGNvbmNlbnRyYXRlZCBwb2RzLg0KDQpUaGVyZWZvcmUsIE5lc2NhZmUgaXMgY29uZHVjdGluZyBleHBlcmltZW50YWwgcmVzZWFyY2ggdG8gaGVscCB0aGVtIGRlY2lkZSB3aGV0aGVyIGl0IHNob3VsZCBsYXVuY2ggdGhlIGNvbmNlbnRyYXRlZCBjb2ZmZWUgcG9kcyB0byByZWNhcHR1cmUgaXRzIHNhbGVzIGFuZCBjb21wZXRlIHdpdGggdGhlc2UgbmV3IGVtZXJnaW5nIGZvcmNlcy4gDQoNCg0KDQojIyMgUmVzZWFyY2ggUXVlc3Rpb25zIGFuZCBIeXBvdGhlc2VzIA0KDQoqKkZlbmd5dWFuIFRpYW4gKDEwMCUpKio6IA0KDQpUaGUgcmVzZWFyY2ggcXVlc3Rpb24gb2YgdGhpcyBzdHVkeSBpczog4oCcV2lsbCB0aGUgbGF1bmNoIG9mIE5lc2NhZmUgY29uY2VudHJhdGVkIGNvZmZlZSBwb2RzIGluY3JlYXNlIE5lc2NhZmXigJlzIHNhbGVzIGluIHRoZSBDaGluZXNlIG1hcmtldD/igJ0NCg0KVGhlIG51bGwgaHlwb3RoZXNpcyBpcyB0aGF0IHRoZSBsYXVuY2ggb2YgTmVzY2FmZSBjb25jZW50cmF0ZWQgY29mZmVlIHBvZHMgd2lsbCBub3QgY2hhbmdlIE5lc2NhZmXigJlzIHNhbGVzIGluIHRoZSBDaGluZXNlIG1hcmtldC4gQW5kIHRoZSBhbHRlcm5hdGl2ZSBoeXBvdGhlc2lzIGlzIHRoYXQgdGhlIGxhdW5jaCBvZiBOZXNjYWZlIGNvbmNlbnRyYXRlZCBjb2ZmZWUgcG9kcyB3aWxsIGNoYW5nZSBOZXNjYWZl4oCZcyBzYWxlcyBpbiB0aGUgQ2hpbmVzZSBtYXJrZXQuDQoNCkFkZHJlc3MgaXQgbWF0aGVtYXRpY2FsbHksIA0KDQokJA0KSF8wIDogXG11IChTYWxlc197UG9kc30pIC0gXG11IChTYWxlc197Tm8gUG9kc30pID0gMA0KJCQNCiQkDQpIX0EgOiBcbXUgKFNhbGVzX3tQb2RzfSkgLSBcbXUgKFNhbGVzX3tObyBQb2RzfSkgXG5lcSAwDQokJA0KDQoNCiMjIyBJbXBvcnRhbmNlIG9mIHRoZSBTdHVkeQ0KDQoqKkZlbmd5dWFuIFRpYW4gKDM0JSkgTWluZ2hhbyBEdSAoMzMlKSBIYW9odWEgTHUgKDMzJSkqKjogDQoNCkZpcnN0IG9mIGFsbCwgdGhlIGNvbmNlbnRyYXRlZCBjb2ZmZWUgcG9kcyBhcmUgYSBicmFuZC1uZXcgcHJvZHVjdCB0aGF0IHRoZXJlIGlzIG5vIHN1ZmZpY2llbnQgZGF0YSBzdWNoIGFzIHNhbGVzIGRhdGEgdG8gYW5hbHl6ZS4gVGhlcmVmb3JlLCBpdCBpcyBuZWNlc3NhcnkgdG8gY29uZHVjdCBwcm9mb3VuZCByZXNlYXJjaCBzaW5jZSBpdCBoYXMgbmV2ZXIgYmVlbiBkb25lIGJlZm9yZS4gDQoNClNlY29uZGx5LCB0aGUgY29zdCBvZiBmYWlsdXJlIG9mIHRoZSBwcm9kdWN0IGNhbiBiZSBudW1lcm91cyBzaW5jZSBtYW51ZmFjdHVyZXJzIGhhdmUgdG8gaW52ZXN0IG1vbmV5IHRvIGJ1aWxkIGEgbmV3IHByb2R1Y3QgbGluZSBhbmQgdG8gbGF1bmNoIGFkdmVydGlzZW1lbnRzLiBMYXJnZXIgbWFudWZhY3R1cmVycyB1c3VhbGx5IGhhdmUgYSBoaWdoZXIgY29zdCBvZiBpbnZlc3RtZW50IHNpbmNlIHRoZXkgd291bGQgbmVlZCB0byBwcm9kdWNlIGxhcmdlciBxdWFudGl0aWVzIHRoYW4gb3RoZXIgbWFudWZhY3R1cmVycy4gVW5saWtlIG90aGVyIHNtYWxsIG1hbnVmYWN0dXJlcnMsIE5lc3RsZSBjYW4gc3BlbmQgdGltZSBhbmQgbW9uZXkgaW4gYWR2YW5jZSB0byBjb25kdWN0IHRoZSByZXNlYXJjaCB0byBsb3dlciB0aGUgcmlzayBhbmQgYXZvaWQgaW52ZXN0bWVudCBmYWlsdXJlLiANCg0KTGFzdGx5LCB0aGUgcmV0dXJuIG9mIHRoZSBleHBlcmltZW50IGlzIHN1YnN0YW50aWFsLiBCeSBjb25kdWN0aW5nIHRoaXMgcmVzZWFyY2gsIHdlIGFyZSBhYmxlIHRvIGNvbGxlY3QgYSBsb3Qgb2YgdGhlIG5ld2VzdCBkYXRhIGluIHRoZSBDaGluZXNlIG1hcmtldC4gQWxzbywgdGhpcyBleHBlcmltZW50YWwgZGVzaWduIGNhbiBiZSB0cmVhdGVkIGFzIGEgYmFzaWMgdGVtcGxhdGUgdGhhdCBOZXN0bGUgY2FuIGFwcGx5IHdoZW4gdGhleSBhcmUgY29uc2lkZXJpbmcgbGF1bmNoaW5nIG5ldyBwcm9kdWN0cyBpbiB0aGUgZnV0dXJlLiANCg0KDQojIyMgTGl0ZXJhdHVyZSBSZXZpZXcNCg0KKipNaW5naGFvIER1ICg1MCUpIEhhb2h1YSBMdSAoNTAlKSoqOiANCg0KVGhlIHB1cnBvc2Ugb2YgdGhpcyByZXNlYXJjaCBpcyB0byBmaW5kIG91dCB3aGV0aGVyIHByb21vdGluZyBhIG5ldyBwcm9kdWN0IHdvdWxkIGltcGFjdCB0aGUgb3ZlcmFsbCBzYWxlcyBvZiB0aGUgY29tcGFueS4gSW4gdGhpcyBzcGVjaWZpYyBjYXNlLCB3ZSBhcmUgbG9va2luZyBmb3IgaG93IHRoZSBDaGluZXNlIGNvZmZlZSBtYXJrZXQgcmVhY3RzIHRvIE5lc2NhZmXigJlzIG5ldyBjb25jZW50cmF0ZWQgY29mZmVlIHBvZHMuIEFzIGluZGljYXRlZCBpbiBGaWd1cmUgMSwgdGhlIHRvdGFsIGNvZmZlZSBjb25zdW1wdGlvbiBpbiBDaGluYSByZXZlYWxzIGFuIHVwd2FyZCB0cmVuZC4gSG93ZXZlciwgRmlndXJlIDIgc3VnZ2VzdGVkIHRoYXQgdGhlIGNvZmZlZSBwcm9kdWN0aW9uIGluIENoaW5hIGlzIHNob3dpbmcgYSBkZWNyZWFzZSBmcm9tIDIwMTgvMTkgdG8gMjAyMC8yMSBhbmQgdGhlIHByb2plY3RlZCBwcm9kdWN0aW9uIGZvciAyMDIxLzIyIGlzIGV4cGVjdGVkIHRvIHJlbWFpbiB0aGUgc2FtZSBhcyAyMDIwLzIxLiBUaHJvdWdoIHRoZSBjaGFuZ2UgaW4gc2FsZXMsIHdlIHdpbGwgYmUgYWJsZSB0byBzZWUgdGhlIGNvbXBhbnnigJlzIHBlcmZvcm1hbmNlIHJlbGF0aXZlIHRvIGl0cyBjb21wZXRpdG9ycyBhcyB3ZWxsIGFzIGl0cyBjb21wZXRpdGl2ZW5lc3MgaW4gdGhlIG1hcmtldC4gKEJha2VyLCBXLiBFLiwgJiBTaW5rdWxhLCBKLiBNLiwgMjAwNSkgDQoNCiMjIyMgQ29mZmVlIG1hcmtldCBpbiBDaGluYQ0KDQpEaWZmZXJlbnQgZnJvbSBvdGhlciBtYXJrZXRzLCB0aGUgQ2hpbmVzZSBjb25zdW1lciBtYXJrZXQgcmVsaWVzIG9uIGJhc2ljIGN1bHR1cmFsIGNvbXBldGVuY2UuIENvbnN1bWVycyBpbiBDaGluYSBoYXZlIGEgdGVuZGVuY3kgdG8gYmUgbW9yZSBhdHRhY2hlZCB0byB0aGVpciBwcmV2aW91cyBleHBlcmllbmNlcyBhbmQgdHJhZGl0aW9ucy4gVGhleSB0ZW5kIHRvIHN0aWNrIHRvIG9uZSBvciB0d28gYnJhbmRzIHRoYXQgdGhleSB0cnVzdCwgdGhpcyBpcyBiYXNlZCBvbiB0aGVpciBwYXN0IGV4cGVyaWVuY2UgYW5kIHRoZXkgYXJlIHVubGlrZWx5IHRvIHN3aXRjaCBicmFuZHMuIChaaGFuZyBOLCAyMDE0KSAgQmFzZWQgb24gdGhpcyBjaGFyYWN0ZXJpc3RpYyBvZiB0aGUgQ2hpbmVzZSBjb25zdW1lciBtYXJrZXQsIGl0IGlzIG1vcmUgbGlrZWx5IGZvciB0aGUgbmV3IHByb2R1Y3QgZnJvbSBOZXN0bGUgQ2FmZSB0byBiZSBhY2NlcHRlZCBieSB0aGUgQ2hpbmVzZSBjb25zdW1lcnMgd2hlbiBjb21wYXJlZCB0byB0aGUgb3RoZXIgY29mZmVlIGJyYW5kcyBjb25zaWRlcmluZyB0aGF0IE5lc3RsZSBDYWZlIGVudGVyZWQgdGhlIENoaW5lc2UgbWFya2V0IHJlbGF0aXZlbHkgZWFybHkgYW5kIGhhcyBidWlsdCB1cCB0aGVpciByZXB1dGF0aW9uIGFtb25nIHRoZSBjb2ZmZWUgY29uc3VtZXJzIGluIENoaW5hLg0KDQoNCiMjIyMgSW1wYWN0IG9mIHRoZSBuZXcgcHJvZHVjdA0KDQpBcyBzdGF0ZWQgaW4gdGhlIHByZXZpb3VzIHNlY3Rpb24sIE5lc2NhZmUgaXMgY29uc2lkZXJpbmcgbGF1bmNoaW5nIGEgbmV3IGNvbmNlbnRyYXRlZCBjb2ZmZWUgcG9kIHByb2R1Y3QgaW4gdGhlIENoaW5lc2UgbWFya2V0LiBUaGVyZSBleGlzdHMgcGFzdCByZXNlYXJjaCB0aGF0IHN0dWRpZWQgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGxhdW5jaGluZyBuZXcgcHJvZHVjdHMgYW5kIHNhbGVzIGdyb3d0aC4gUmVmZXJyaW5nIExpICYgTGluLCAyMDE1LCBpdCBleHBsb3JlZCB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gc2FsZXMgcGVyZm9ybWFuY2UgYW5kIHNldmVyYWwgaW1wYWN0aW5nIGZhY3RvcnMgdGhhdCBhcmUgYXNzb2NpYXRlZCB3aXRoIGltcG9ydGVkIG5ldyBwcm9kdWN0cy4gSW4gdGhpcyBzdHVkeSwgdGhlIHJlc2VhcmNoIHJlc3VsdHMgZGVtb25zdHJhdGVkIHRoYXQgcHJvZHVjdCBtZWFuaW5nZnVsbmVzcyAocCA8IC4wMSksIHByb2R1Y3Qgc3VwZXJpb3JpdHkgKHAgPCAuMDAxKSwgYW5kIGN1c3RvbWVyIGZhbWlsaWFyaXR5IChwIDwgLjAwMSkgYXJlIGhhdmluZyBwb3NpdGl2ZSBhbmQgc2lnbmlmaWNhbnQgZWZmZWN0cyBvbiBuZXcgcHJvZHVjdOKAmXMgc2FsZXMgcGVyZm9ybWFuY2UuIA0KDQojIyMjIEEgcHJldmlvdXMgc3R1ZHkgb2YgdGhlIGNvbnN1bWVyc+KAmSB3aWxsaW5nbmVzcyB0byBwYXkgZm9yIGNvZmZlZSBpbiBDaGluYQ0KDQpXZSB3b3VsZCBhbHNvIGxpa2UgdG8ga25vdyBob3cgY29mZmVlIGNvbnN1bWVycyBvZiBDaGluYSB3aWxsIHJlYWN0IHdoZW4gdGhlcmUgaXMgYSBuZXcgcHJvZHVjdCBiZWluZyBpbnRyb2R1Y2VkIHRvIHRoZSBtYXJrZXQuIFlhbmcgZXQgYWwuKDIwMTIpIHJlc2VhcmNoZWQgdG8gZmluZCBvdXQgd2hldGhlciB0aGUgYW1vdW50IG9mIGluZm9ybWF0aW9uIHJlZ2FyZGluZyB0aGUgcHJvZHVjdCB3b3VsZCBiZSBjb25zaWRlcmVkIGFzIGEgZmFjdG9yIHdoZW4gdGhlIGN1c3RvbWVycyBhcmUgbWFraW5nIHRoZWlyIGRlY2lzaW9uLiBUaGUgc3R1ZHkgaW1wbGVtZW50ZWQgbWF4aW11bSBsaWtlbGlob29kIGVzdGltYXRpb24gd2hpbGUgdXNpbmcgbGluZWFyIG9yZGluYXJ5IGxlYXN0IHNxdWFyZSAoT0xTKSByZWdyZXNzaW9uIHRvIHByb3ZpZGUgYSBiYXNlbGluZSBlc3RpbWF0ZSBmb3IgdGhlIHBhcmFtZXRlcnMgaW52b2x2ZWQuIEZvdXIgb2YgdGhlIGNvZWZmaWNpZW50cyAoYWdlLCBtYXJyeSwgZmxhdm9yIGFuZCBvcmdfa25vd24pIHN0b29kIG91dCBhcyB0aGV5IHdlcmUgbWVhc3VyZWQgd2l0aCBjb25zaXN0ZW50IHNpZ25zIGFuZCBzaWduaWZpY2FuY2Ugd2l0aCDigJxtYXJyeeKAnSBhbmQg4oCcZmxhdm9y4oCdIGJlaW5nIG1vc3RseSBtYXJnaW5hbCBzaWduaWZpY2FudC4gVGhlcmVmb3JlLCB0aGUgcmVzZWFyY2ggcmVmbGVjdHMgdGhhdCBub3QgYWxsIGNvbnN1bWVycyBhcmUgd2lsbGluZyB0byBwYXkgdGhlIHNhbWUgYW1vdW50IGZvciBhIGZhaXIgdHJhZGUgY29mZmVlLiBVcG9uIGZ1cnRoZXIgY2xhc3NpZmljYXRpb24gYmFzZWQgb24gdGhlIGNvbnN1bWVyc+KAmSBkZW1vZ3JhcGhpYyBmZWF0dXJlcyBhbmQgYWdlLCB3ZSB3b3VsZCBleHBlY3QgYSBkaWZmZXJlbmNlIGluIGN1c3RvbWVyIHdpbGxpbmduZXNzIHRvIHB1cmNoYXNlLg0KDQoNCg0KIyMjIFJlc2VhcmNoIFBsYW4NCg0KKipKaWFtYW4gTGkgKDUwJSkgWGlhbmdwaW5nIFpob3UgKDUwJSkqKjoNCg0KIyMjIyBQb3B1bGF0aW9uIG9mIEludGVyZXN0DQoNClNpbmNlIHRoZSBtYXJrZXQgc2NvcGUgb2YgbGF1bmNoaW5nIGxpcXVpZCBjb25jZW50cmF0ZWQgY29mZmVlIHBvZHMgaXMgaW4gZmlyc3QtdGllciwgTmV3IGZpcnN0LXRpZXIsIHNlY29uZC10aWVyLCBhbmQgdGhpcmQtdGllciBjaXRpZXMuIEluIENoaW5hLCBjaXRpZXMgYXJlIHJhbmtlZCBiYXNlZCBvbiB0aGVpciBlY29ub21pYyBsZXZlbCBvZiBjaXRpZXMgYW5kIHJlZmxlY3QgZGlmZmVyZW5jZXMgaW4gbG9jYWwgaW5jb21lIGxldmVsLCBwb3B1bGF0aW9uLCBpbmZyYXN0cnVjdHVyZSwgdGFsZW50IHBvb2wsIGJ1c2luZXNzIG9wcG9ydHVuaXRpZXMsIGV0Yy4gT3VyIGdyb3VwIHNlbGVjdHMgdGhlIGdlbmVyYWwgcHVibGljIGF0IHRoZXNlIFRpZXIgY2l0aWVzIGFzIG91ciBwb3B1bGF0aW9uIG9mIGludGVyZXN0LiBUbyBiZSBzcGVjaWZpYywgdGhlIGdlbmVyYWwgcHVibGljIGluY2x1ZGVzOg0KLSAgIEV4aXN0aW5nIGNvbnN1bWVycyBvZiBOZXN0bMOpIGJyYW5kIGFuZCBjb2ZmZWUgcHJvZHVjdHMNCi0gICBDb25zdW1lcnMgd2hvIGJ1eSBjb2ZmZWUgcHJvZHVjdHMgYnV0IG5vdCB0aGUgTmVzdGzDqSBicmFuZA0KDQoNCiMjIyMgU2FtcGxlIFNlbGVjdGlvbg0KDQpUaGUgbWFyZ2luIG9mIGVycm9yID0gNSUNCkNvbmZpZGVuY2UgbGV2ZWwgPSA5NSUNCg0KUG9wdWxhdGlvbiBTaXplOiAxMTkgY2l0aWVzDQoNCnwgQ2xhc3NpZmljYXRpb24gCXwgIG4gIAl8DQp8Oi0tLS0tLS0tLS0tLS0tOgl8Oi0tLToJfA0KfCBGaXJzdC10aWVyICAgICAJfCAgNCAgCXwNCnwgTmV3IGZpcnN0LXRpZXIgCXwgIDE1IAl8DQp8IFNlY2VuZC10aWVyICAgIAl8ICAzMCAJfA0KfCBUaGlyZC10aWVyICAgIAl8ICA3MCAJfA0KfCAgICAgIFRvdGFsICAgICAJfCAxMTkgCXwNCg0KIA0KU2FtcGxlID0gNTQgY2l0aWVzDQoNCnwgQ2xhc3NpZmljYXRpb24gCXwgVHJlYXRtZW50IAl8IENvbnRyb2wgCXwNCnw6LS0tLS0tLS0tLS0tLS06CXw6LS0tLS0tLS0tOgl8Oi0tLS0tLS06CXwNCnwgRmlyc3QtdGllciAgICAgCXwgICAgIDEgICAgIAl8ICAgIDEgICAgCXwNCnwgTmV3IGZpcnN0LXRpZXIgCXwgICAgIDcgICAgIAl8ICAgIDcgICAgCXwNCnwgU2VjZW5kLXRpZXIgICAgCXwgICAgIDEzICAgIAl8ICAgIDEzICAgCXwNCnwgVGhpcmQtdGllciAgICAJfCAgICAgMzMgICAgCXwgICAgMzMgICAJfA0KfCAgICAgIFRvdGFsICAgICAJfCAgICAgNTQgICAgCXwgICAgNTQgICAJfA0KDQojIyMjIFNhbXBsZSBTaXplDQoNCk91ciB0ZWFtIGRlY2lkZWQgdG8gc2VsZWN0IG91ciBzYW1wbGVzIGZyb20gdGhlIHJlcHJlc2VudGF0aXZlIGNpdGllcyBpbiBmaXJzdC10aWVyLCBuZXcgZmlyc3QtdGllciwgc2Vjb25kLXRpZXIsIGFuZCB0aGlyZC10aWVyIGNpdHktbGlzdCBiYXNlZCBvbiB0aGUgaGllcmFyY2hpY2FsIGNsYXNzaWZpY2F0aW9uIG9mIGNpdGllcyBpbiBDaGluYS4gQWNjb3JkaW5nIHRvIHRoZSBkYXRhIG9mIHRoZSBDaGluYSBCdXNpbmVzcyBOZXR3b3JrLCBDaGluYSBoYXMgNCBmaXJzdC10aWVyIGNpdGllcywgMTUgTmV3IGZpcnN0LXRpZXIgY2l0aWVzLCAzMCBzZWNvbmQtdGllciBjaXRpZXMsIGFuZCA3MCB0aGlyZC10aWVyIGNpdGllcyBpbiAyMDIxLCB3aXRoIGEgdG90YWwgb2YgMTE5LiBCeSBzZXR0aW5nIHRoZSBjb25maWRlbmNlIGludGVydmFsIGF0IDk1JSwgbWFyZ2luIGVycm9yIGF0IDEwJSwgYW5kIHJlc3BvbnNlIGRpc3RyaWJ1dGlvbiBhdCA1MCUsIHdlIGNvbWUgdXAgd2l0aCBhIHNhbXBsZSBzaXplIHdpdGggYSB0b3RhbCBvZiA1NCwgd2hpY2ggaW5jbHVkZSAxIGNpdHkgZnJvbSB0aGUgZmlyc3QtdGllciBjaXR5LCA3IGNpdGllcyBmcm9tIHRoZSBuZXcgZmlyc3QtdGllciBjaXR5LCAxMyBjaXRpZXMgZnJvbSB0aGUgc2Vjb25kLXRpZXIgY2l0eSwgYW5kIDMzIGNpdGllcyBmcm9tIHRoZSB0aGlyZC10aWVyIGNpdHkuIEluIHRoZSBkZXRhaWxzLCB0aGUgbnVtYmVyIG9mIHNhbXBsZSBjaXRpZXMgaW4gZWFjaCB0aWVyIGlzIGNhbGN1bGF0ZWQgYnkgdGhlIHJhdGlvIG9mIHRoZSB0b3RhbCBudW1iZXIgb2YgY2l0aWVzIGluIGVhY2ggdGllci4gQWxzbywgdGhlIHNlbGVjdGVkIGNpdGllcyBpbiBlYWNoIHRpZXIgc2hvdWxkIGJlIHJlcHJlc2VudGF0aXZlIG9mIG90aGVyIGNpdGllcyBpbiB0aGUgc2FtZSB0aWVyIGJhc2VkIG9uIHNvbWUgaW5kaWNhdG9ycyBzdWNoIGFzIGVjb25vbWljIGxldmVsLCBkZW1vZ3JhcGhpYyBjaGFyYWN0ZXJpc3RpY3MsIGFuZCB0aGUgbGV2ZWwgb2Ygc29waGlzdGljYXRpb24gaW4gcHJvZHVjdHMgYW5kIHNlcnZpY2VzLg0KDQoNCiMjIyMgT3BlcmF0aW9uYWwgUHJvY2VkdXJlcw0KDQotICoqU3RlcCAxOioqIEJhc2VkIG9uIHRoZSBoaWVyYXJjaGljYWwgY2xhc3NpZmljYXRpb24gb2YgY2l0aWVzIGluIENoaW5hLCBvdXIgdGVhbSB1c2VkIHNpbXBsZSByYW5kb20gc2FtcGxpbmcgdG8gc2VsZWN0IGNpdGllcyBmcm9tIGVhY2ggdGllciBvZiBjaXRpZXMgaW4gQ2hpbmEgYW5kIGZvcm1lZCBvdXIgdHJlYXRtZW50IGFuZCBjb250cm9sIGdyb3Vwcy4gSW4gZGV0YWlsLCBlYWNoIGdyb3VwIGhhcyA1NCBjaXRpZXMgaW4gdG90YWw6IDEgZmlyc3QtdGllciBjaXR5LCA3IG5ldyBmaXJzdC10aWVyIGNpdGllcywgMTMgc2Vjb25kLXRpZXIgY2l0aWVzLCBhbmQgMzMgdGhpcmQtdGllciBjaXRpZXMuIEluIHRoZSB0cmVhdG1lbnQgY2l0eSBncm91cCwgd2Ugd2lsbCByZWxlYXNlIHRoZSBOZXNjYWbDqSBDb25jZW50cmF0ZWQgQ29mZmVlIFBvZHMgZm9yIHNhbGUsIGFuZCBmb3IgY2l0aWVzIGluIHRoZSBjb250cm9sIGdyb3VwLCB3ZSB3aWxsIG5vdCBsYXVuY2ggdGhlIG5ldyBwcm9kdWN0LiBCZXNpZGVzLCB3ZSB3aWxsIGtlZXAgdGhlIG9wZXJhdGlvbiBvZiB0aGUgcHJldmlvdXMgZXhpc3RpbmcgcHJvZHVjdHMgaW4gdGhlc2UgY2l0aWVzLg0KDQotICoqU3RlcCAyOioqIExhdW5jaCBOZXNjYWbDqSBDb25jZW50cmF0ZWQgQ29mZmVlIFBvZHMgdG8gNTQgc2VsZWN0ZWQgY2l0aWVzIGluIHRoZSB0cmVhdG1lbnQgZ3JvdXAgYW5kIHB1dCBuZXcgcHJvZHVjdHMgb24gdGhlIHNoZWx2ZXMgb2YgYnJpY2stYW5kLW1vcnRhciBzdG9yZXMsIGluY2x1ZGluZyBzbWFsbCBjaGFpbiBjb252ZW5pZW5jZSBzdG9yZXMgc3VjaCBhcyA3LUVsZXZlbiBhbmQgbWVkaWFuIGFuZCBsYXJnZSBncm9jZXJ5IHN0b3JlcyBzdWNoIGFzIFdhbG1hcnQsIG9uIERlY2VtYmVyIDFzdCwgMjAyMS4gQWRkaXRpb25hbGx5LCB0aGUgc21hbGwgcHJpdmF0ZSBzdG9yZXMgd2lsbCBub3QgY2FycnkgdGhlIHByb2R1Y3QgYW5kIGJlIGV4Y2x1ZGVkIGZyb20gdGhlIHRyZWF0bWVudCBzaW5jZSB0aG9zZSBzdG9yZXMgaGF2ZSBsaW1pdGVkIHNhbGVzIGluZm9ybWF0aW9uIHRoYXQgbGFja3Mgc3RhbmRhcmRpemF0aW9uIGFuZCBoYXMgbG93IGFjY3VyYWN5LiBBcyBhIHJlc3VsdCwgdGhlIGRhdGEgY29sbGVjdGlvbiBwcm9jZWR1cmUgd2lsbCBiZSBjb21wbGljYXRlZCwgYW5kIHRoZSBhY2N1cmFjeSBvZiBvdXIgc3R1ZHkgd2lsbCBiZSBhZmZlY3RlZC4NCg0KLSAqKlN0ZXAgMzoqKiBDb2xsZWN0IHNhbGVzIGRhdGEgZnJvbSBvdXIgY29udHJvbCBncm91cCBhbmQgdHJlYXRtZW50IGdyb3VwIGluIG9uZSB5ZWFyIGJhc2VkIG9uIHRoZSBzYWxlIGN5Y2xlIG9mIHRoZSBOZXNjYWbDqSBDb25jZW50cmF0ZWQgQ29mZmVlIFBvZHMuDQoNCi0gKipTdGVwIDQ6KiogVGlkeSBzYWxlcyBkYXRhIGFuZCB0dXJuIGl0IGludG8gYnVzaW5lc3MgbWV0cmljcyB0aGF0IGNvdWxkIHByb3ZlIHRoZSBtYXJrZXQgZWZmZWN0aXZlbmVzcyBvZiB0aGUgTmVzY2Fmw6kgQ29uY2VudHJhdGVkIENvZmZlZSBQb2RzLg0KDQotICoqU3RlcCA1OioqIENvbXBhcmUgdGhlIG92ZXJhbGwgY2hhbmdlcyBpbiBzYWxlcyBvZiBOZXN0bGXigJlzIGNvZmZlZSBidXNpbmVzcyBpbiB0aGUgdGVzdCBhbmQgY29udHJvbCBncm91cHMuDQoNCi0gKipTdGVwIDY6KiogQ29uY2x1ZGUgdGhlIHRlc3QgYW5kIGNvbWUgdXAgd2l0aCBhIHJlY29tbWVuZGF0aW9uIG9mIE5lc2NhZsOpIENvbmNlbnRyYXRlZCBDb2ZmZWUgUG9kc+KAmSBsYXVuY2ggcGxhbi4NCg0KDQojIyMgQnJpZWYgU2NoZWR1bGUNCg0KfCBCZWhhdmlvciAJfCBUaW1lICAJfCBQYXJ0aWNpcGFudHMgCXwNCnw6LS0tOgl8Oi0tLToJfDotLS06CXwNCnwgUGVyZm9ybSB0aGUgZXhwZXJpbWVudDogTGF1bmNoIG5ldyBwcm9kdWN0cyBpbiB0aGUgdHJlYXRtZW50IGNpdHkgZ3JvdXAgCXwgSmFudWFyeSAxc3QsIDIwMjIgCXwgVGhlIGNoYWluIHN0b3JlcyBzZWxlY3RlZCBmb3IgMTA4IGNpdGllczxicj4oNTQgY2l0aWVzIGVhY2ggaW4gdGhlIHRyZWF0bWVudCBhbmQgY29udHJvbCBncm91cHMpIAl8DQp8IEVuZCBvZiB0aGUgZXhwZXJpbWVudCAJfCBEZWNlbWJlciAzMXN0LCAyMDIyIAl8ICAJfA0KfCBDb2xsZWN0IHNhbGVzIGRhdGEgCXwgSmFudWFyeSAxc3QsIDIwMjMgdG8gSmFudWFyeSAzMXN0LCAyMDIzIAl8ICAJfA0KfCBTdGF0aXN0aWNhbCBBbmFseXNpcyBvZiB0aGUgYWNxdWlyZWQgZGF0YSAJfCBGZWJydWFyeSAxc3QsIDIwMjMgdG8gRmVicnVhcnkgMTV0aCwgMjAyMyAJfCAgCXwNCg0KDQojIyMjIERhdGEgQ29sbGVjdGlvbg0KDQpPdXIgZGF0YSBjb2xsZWN0aW9uIHdpbGwgYmUgYmFzZWQgb24gc2hvcHMnIHNhbGVzIGluIG91ciBjb250cm9sIGdyb3VwIGFuZCB0cmVhdG1lbnQgZ3JvdXAuIFN0b3JlcyB1bmRlciB0aGUgcmV0YWlsIGNoYW5uZWwgd2lsbCBoYXZlIHNhbGVzIHJlY29yZHMgb2YgTmVzdGzDqSBjb2ZmZWUuIFdlIGNvbGxlY3QgdGhlIHN0b3JlIHNhbGVzIGRhdGEgb2Ygb3VyIG5ldyBwcm9kdWN0cyBpbiB0aGUgc2FtcGxlIGNpdGllcyBldmVyeSBtb250aCBmcm9tIG91ciB0cmVhdG1lbnQgYW5kIGNvbnRyb2wgZ3JvdXBzLCA1NCBjaXRpZXMgaW4gZWFjaCBncm91cC4gRm9yIGZ1cnRoZXIgdGVzdGluZywgd2Ugd2lsbCB1c2UgY2l0eS1sZXZlbCBkYXRhIGNvbnRhaW5pbmcgMTA4IG9ic2VydmF0aW9uYWwgcm93cy4gV2Ugd291bGQgdGhlbiBjb21wYXJlIHRoZSBtZWFuIHNhbGVzIHZvbHVtZSBvZiB0aGUgY29udHJvbCBhbmQgdHJlYXRtZW50IGNpdGllcyBhZnRlciBjb25kdWN0aW5nIHRoZSB0ZXN0LiBJbiBhZGRpdGlvbiwgc29tZSBjb25mb3VuZGluZyB2YXJpYWJsZXMsIHN1Y2ggYXMgcHJvbW90aW9uYWwgYWN0aXZpdGllcyBhbmQgY29mZmVlIGNvbnN1bXB0aW9uIHRyZW5kcywgbWF5IGNvZXhpc3QgYW5kIGltcGFjdCBvdXIgc3R1ZHksIHVuZGVyZXN0aW1hdGluZyB0aGUgaW1wYWN0IG9mIHRoZSBuZXdseSBsYXVuY2hlZCBOZXNjYWbDqSBDb25jZW50cmF0ZWQgQ29mZmVlIFBvZHMgb24gbWFya2V0IHNhbGVzLiBXZSB3b3VsZCByYW5kb21seSBzZWxlY3QgY2l0aWVzIGZvciB0aGUgY29udHJvbCBhbmQgdHJlYXRtZW50IGdyb3VwcyB0byBtaW5pbWl6ZSB0aGUgZWZmZWN0IG9mIGNvbmZvdW5kaW5nIHZhcmlhYmxlcy4NCg0KDQoNCiMjIyMgRGF0YSBTZWN1cml0eQ0KDQpTaW5jZSB3ZSBvbmx5IGNvbGxlY3QgdGhlIHNhbGVzIHZvbHVtZSBhbmQgYW1vdW50IGRhdGEsIHRoZXJlIGlzIG5vIHNlbnNpdGl2ZSBkYXRhIHJlbGF0ZWQgdG8gY3VzdG9tZXJz4oCZIHBlcnNvbmFsIGluZm9ybWF0aW9uLCBzbyB0aGVyZSB3aWxsIGJlIG5vIHByaXZhY3kgcHJvYmxlbXMuDQoNCg0KIyMjIyBPdXRjb21lcyAoRGVwZW5kZW50IFZhcmlhYmxlcykNCg0KRGVwZW5kZW50IFZhcmlhYmxlIChZKTogVG90YWwgc2FsZXMgb2YgTmVzY2Fmw6kgKE5lc3Rsw6kgU0EpIGluIGEgZmlzY2FsIHBlcmlvZC4NCg0KDQojIyMjIFRyZWF0bWVudHMgKEluZGVwZW5kZW50IFZhcmlhYmxlcykNCg0KSW5kZXBlbmRlbnQgVmFyaWFibGUgKFgpOiBUaGUgbGF1bmNoIG9mIE5lc3Rsw6kgY29uY2VudHJhdGVkIGNvZmZlZSBwb2RzIChZZXM9MSwgTm89MCkNCkNvbnNpZGVyaW5nIG91ciBpbmRlcGVuZGVudCB2YXJpYWJsZSBpcyBhIGR1bW15IHZhcmlhYmxlLCB3ZSB1c2UgYSBUd28tc2FtcGxlIHQtdGVzdCB0byBtZWFzdXJlIHRoZSBlZmZlY3RpdmVuZXNzIG9mIHRoZSBsYXVuY2ggb2YgTmVzdGzDqSBjb25jZW50cmF0ZWQgY29mZmVlIHBvZHMgb24gdGhlIHRvdGFsIHNhbGVzIG9mIE5lc2NhZsOpLCBhbmQgYXNzdW1lIHRoZSBtb2RlbCBhczoNCg0KJCQNCllfaSA9IGJfMVhfaStiXzIrdV9pDQokJA0KDQpXaGVyZSBZIGlzIHRoZSB0b3RhbCBzYWxlcyBvZiBOZXNjYWbDqSAoTmVzdGzDqSBTQSkgaW4gYSBmaXNjYWwgcGVyaW9kLCBhbmQNCg0KJCQgDQpYID0NClxiZWdpbntjYXNlc30NCjEgPSBZZXNcXA0KMCA9IE5vDQpcZW5ke2Nhc2VzfQ0KJCQgDQoNCklmIHdlIGxhdW5jaCB0aGUgbmV3IHByb2R1Y3QsIHdoaWNoIG1lYW5zIFggPSAxLCBicmluZyBpdCBpbnRvIHRoZSBtb2RlbCBhbmQgd2UgZ2V0Og0KJFlfaT1iXzErYl8yK3VfaSQsIHRoZSBleHBlY3RlZCB2YWx1ZSBpcyAke0UoWX1faSk9Yl8xK2JfMiQNCg0KSW4gY29udHJhc3QsIGlmIHdlIGRvbuKAmXQgbGF1bmNoIHRoZSBuZXcgcHJvZHVjdCwgd2hpY2ggbWVhbnMgWCA9IDAsIGJyaW5nIGl0IGludG8gdGhlIG1vZGVsIGFuZCB3ZSBnZXQ6DQokWV9pPWJfMit1X2kkLCB0aGUgZXhwZWN0ZWQgdmFsdWUgaXMgJHtFKFl9X2kpPWJfMiQNCg0KT3VyIG51bGwgaHlwb3RoZXNpcyBhc3N1bWVzIHRoYXQgdGhlIHRvdGFsIHNhbGVzIG9mIE5lc2NhZsOpIHdpdGggdGhlIGxhdW5jaCBvZiB0aGUgY29uY2VudHJhdGVkIGNvZmZlZSBwb2RzIHdpbGwgYmUgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQgZnJvbSB0aGF0IHdpdGhvdXQgdGhlIGxhdW5jaCwgYW5kIHRoZSBhdmVyYWdlIGRpZmZlcmVuY2UgaXMgdGhlIGNvZWZmaWNpZW50IG9mIFguDQoNClRoZSBjYXRlZ29yeSB3aXRoIHplcm8gdmFsdWUgaXMgY2FsbGVkIHRoZSBiYXNlLCB0aGUgYmVuY2htYXJrIGZvciBjb21wYXJpc29uIHdpdGggb3RoZXIgY2F0ZWdvcmllcy4gVGhlIGNvbW1vbiBpbnRlcmNlcHQgaXRlbSBpcyB0aGUgaW50ZXJjZXB0ZWQgaXRlbSBvZiB0aGUgYmFzZSBjbGFzcy4NCg0KJGJfMSQgaXMgY2FsbGVkIGRpZmZlcmVudGlhbCBpbnRlcmNlcHQgY29lZmZpY2llbnQsIHdoaWNoIGluZGljYXRlcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBpbnRlcmNlcHQgdmFsdWUgb2YgdGhlIGNhdGVnb3J5IHdpdGggYSB2YWx1ZSBvZiAxIGFuZCB0aGUgaW50ZXJjZXB0IHZhbHVlIG9mIHRoZSBiYXNlIGNsYXNzLg0KDQpXZSB3aWxsIHVzZSBhIHR3by1zYW1wbGUgdGVzdCB0byB0ZXN0IHdoZXRoZXIgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgY2xhc3NpZmljYXRpb24gd2l0aCBYIGVxdWFsIHRvIDEgYW5kIHRoZSBiYXNlIGNsYXNzIGlzIHNpZ25pZmljYW50Lg0KDQoNCg0KIyMjIyBPdGhlciBWYXJpYWJsZXMNCg0KKipGZW5neXVhbiBUaWFuICgxMDAlKSoqOiANCg0KfCBWYXJpYWJsZXMgCXwgUG9zc2libGUgVmFsdWVzIAl8IERlc2NyaXB0aW9ucyAJfA0KfDotLS06CXw6LS0tOgl8Oi0tLToJfA0KfCBSZXRhaWwgUHJpY2UgCXwgJDMgcGVyIGJhZyAJfCBJbiB0aGlzIHJlc2VhcmNoLCB3ZSBtdXN0IG1ha2Ugc3VyZSB0aGF0IHRoZSBzYW1lIHJldGFpbCBwcmljZSBmb3IgdGhpcyBwcm9kdWN0IGlzIGluIGVhY2ggc3RvcmUuIAl8DQp8IFBhY2thZ2luZyAJfCBUaGUgYXBwZWFyYW5jZSBvZiB0aGUgcHJvZHVjdCAJfCBUaGUgZGVzaWduIGFuZCB0aGUgcGFja2FnaW5nIGFwcGVhcmFuY2UgYXJlIHRoZSBzYW1lLiAJfA0KfCBNYXJrZXRpbmcgc3RyYXRlZ3kgCXwgTnVtYmVyIG9mIGFkdmVydGlzZW1lbnQgCXwgSW4gdGhpcyBleHBlcmltZW50LCB3ZSBkaWQgbm90IHByb3Bvc2UgYW55IGFkdmVydGlzZW1lbnQgZm9yIHRoZSBjb25jZW50cmF0ZWQgY29mZmVlIHBvZHMsIHdlIG5lZWRlZCB0byBtYWtlIHN1cmUgdGhhdCBlYWNoIHN0b3JlIHdvdWxkIG5vdCBtYWtlIGFueSBhZHZlcnRpc2VtZW50IGZvciB0aGlzIHByb2R1Y3QuIAl8DQp8IENhcGFjaXR5IAl8IDI1IG1sIAl8IFdlIG5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIGNhcGFjaXR5IGlzIGNvbnN0YW50IGZvciBhbGwgcG9kcy4gCXwNCg0KDQojIyMgU3RhdGlzdGljYWwgQW5hbHlzaXMgUGxhbiAgDQoNCioqSGFvaHVhIEx1ICg1MCUpIE1pbmdoYW8gRHUgKDUwJSkqKjogDQoNCkR1ZSB0byB0aGUgbmF0dXJlIG9mIHdoaWNoIGRhdGEgaW4gdGhpcyBzdHVkeSB3aWxsIGJlIHNpbXVsYXRlZCwgdGhlIHRlYW0gd2lsbCBwcmVkZXRlcm1pbmUgc29tZSBhdHRyaWJ1dGUgdmFsdWVzIGZvciBzYWxlcyBkYXRhIGdlbmVyYXRpb24uIEluIHRoZSBhbmFseXNpcyBzdGFnZSwgd2Ugd2lsbCBwZXJmb3JtIGV4cGxvcmF0b3J5IGFuZCBxdWFudGl0YXRpdmUgYW5hbHlzaXMgb24gdGhlIHNpbXVsYXRlZCBkYXRhLiBCb3RoIG9mIHdoaWNoIHdpbGwgaGVscCB0aGUgdGVhbSBiZXR0ZXIgYXNzZXNzIHRoZSByZXN1bHQgb2YgdGhlIGV4cGVyaW1lbnQuIFRoZXkgYWxzbyBoZWxwIHRoZSB0ZWFtIGJldHRlciB1bmRlcnN0YW5kIHRoZSBvdmVyYWxsIGdlb21ldHJpY3Mgb2YgcmVzcG9uc2UgdmFsdWVzIGFjcm9zcyBkaWZmZXJlbnQgcGFyYW1ldGVyIHZhbHVlIGNvbWJpbmF0aW9ucy4gDQoNCiMjIyMgRGF0YSBzaW11bGF0aW9uDQoNClRvIGdlbmVyYXRlIHRoZSBtb3N0IHJlYWxpc3RpYyBzYWxlcyBkYXRhLCB3ZSBkZWNpZGVkIHRvIHVzZSB0aGUgZXhpc3RpbmcgZGF0YSByZWdhcmRpbmcgdGhlIGNvdW50IG9mIGNvZmZlZSBjb21wYW5pZXMgaW4gZGlmZmVyZW50IGNpdHkgdGllcnMgdG8gaGVscCBkZWNpZGUgdGhlIG1lYW4gb2Ygc2FsZTsgYXMgdGhpcyByZWZsZWN0cyBjdXN0b21lcnMgaW4gZ2l2ZW4gY2l0aWVz4oCZIGNvZmZlZSBkZW1hbmRpbmduZXNzLCB0byBzb21lIGRlZ3JlZSBvZiBleHRlbnQuIFN1Y2ggdGhhdCwgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBvZiBzYWxlcyBjYW4gYWxzbyBiZSBjYWxjdWxhdGVkIGZyb20gdGhlIHNhbWUgZGF0YSBzZXQuIEJlZm9yZSBnZW5lcmF0aW5nIHNhbGVzIGRhdGEsIG1lYW4gYW5kIHN0YW5kYXJkIGRldmlhdGlvbiBkaWZmZXJlbmNlcyBiZXR3ZWVuIGNpdHkgdGllcnMgYXJlIG5vcm1hbGl6ZWQuIEZvciB0aGUgYmFzZWxpbmUgc2FsZXMgbWVhbiwgdGhlIHRlYW0gYXJiaXRyYXJpbHkgY2hvc2UgMTAwLCBhbmQgMTAgZm9yIHN0YW5kYXJkIGRldmlhdGlvbi4gSW4gb3JkZXIgdG8gb2J0YWluIHRoZSBtb3N0IHJlcHJlc2VudGF0aXZlIGRhdGEsIHdlIGRlY2lkZWQgdG8gcnVuIHRoZSBzaW11bGF0aW9uIDEwMDAgdGltZXMgdG8gY2FwdHVyZSB0aGUgZGVzaWduYXRlZCBzYWxlcyBkYXRhIGRpc3RyaWJ1dGlvbi4gIA0KCQ0KIyMjIyBFeHBsb3JhdG9yeSBhbmFseXNpcyANCg0KQnkgcGVyZm9ybWluZyBleHBsb3JhdG9yeSBhbmFseXNpcywgd2UgZmlyc3QgdGFrZSBhIGdsYW5jZSBhdCBvdXIgZGF0YSB0byBzcG90IHRoZSBwYXR0ZXJucyBpZiB0aGVyZSBhcmUgYW55LiBPdGhlciB0aGFuIHRoYXQsIHNldmVyYWwgcGxvdHMgd2lsbCBiZSBnZW5lcmF0ZWQgdG8gbWFrZSBzdXJlIGRhdGEgc2ltdWxhdGVkIGFyZSBhcyBleHBlY3RlZC4gRm9sbG93aW5nIHRoYXQsIHdlIHdpbGwgYWxzbyBjYWxjdWxhdGUgc3RhdGlzdGljIHByb3BlcnRpZXMgb2YgdGhlIHNpbXVsYXRlZCBkYXRhIHRvIG1ha2Ugc2Vuc2Ugb2YgdGhlIG92ZXJhbGwgZGF0YSBnZW9ncmFwaGljLiANCg0KIyMjIyBRdWFudGl0YXRpdmUgYW5hbHlzaXMgDQoNClR3byBzYW1wbGUgdC10ZXN0cyB3aWxsIGJlIHBlcmZvcm1lZCBiYXNlZCBvbiB0aGUgbnVsbCBoeXBvdGhlc2lzIGJlaW5nIHRoYXQgcHJvbW90aW5nIGEgbmV3IHR5cGUgb2YgY29mZmVlIGhhcyBubyBlZmZlY3Qgb24gTmVzdGxl4oCZcyBjb2ZmZWUgc2FsZSBhbmQgdGhlIGFsdGVybmF0aXZlIGh5cG90aGVzaXMgYmVpbmcgdGhhdCB0aGUgbmV3IHR5cGUgb2YgY29mZmVlIGRvZXMgaGF2ZSBzb21lIGVmZmVjdC4gV2UgY2hvb3NlIHRvIHBlcmZvcm0gYSB0d28tc2FtcGxlIHQtdGVzdCBzaW5jZSB0aGUgcHJlZGljdGluZyBzYWxlcyBhcmUgY29udGludW91cyBhbmQgd2UgYXJlIGFpbWluZyB0byBjb21wYXJlIHRoZSBkaWZmZXJlbmNlIGluIHRoZSBtZWFuIGJldHdlZW4gdGhlIHRyZWF0bWVudCBncm91cCBhbmQgdGhlIGNvbnRyb2xsZWQgZ3JvdXAuIEluIHRlcm1zIG9mIG91ciBzYW1wbGUgcG9wdWxhdGlvbiwgIHRoZSBjb250cm9sbGVkIGdyb3VwIGFuZCB0cmVhdG1lbnQgZ3JvdXBzIGluIG91ciBzdHVkeSBhcmUgZ3JvdXBlZCBiYXNlZCBvbiB0aGUgbGV2ZWwgb2YgY2l0aWVzLiBXZSBjb25zaWRlciBmb2N1c2luZyBvbiB0aGUgcG93ZXIsIHAtdmFsdWUsIGFuZCBlZmZlY3Qgc2l6ZSByZXN1bHRpbmcgZnJvbSBvdXIgdGVzdC4gU2NlbmFyaW9zIGxpa2Ugc2lnbmlmaWNhbnQgcC12YWx1ZSB3aXRoIGxvdyBwb3dlciBhbmQgaW5zaWduaWZpY2FudCBwLXZhbHVlIHdpdGggaGlnaCBwb3dlciBhcmUgbm90IGFjY2VwdGFibGUgZnJvbSB0aGUgb3V0Y29tZS4NCg0KDQojIyMgTGltaXRhdGlvbnMgYW5kIFVuY2VydGFpbnRpZXMNCg0KKipNaW5naGFvIER1ICgyMCUpIEhhb2h1YSBMdSAoMjAlKSBGZW5neXVhbiBUaWFuICgyMCUpIEppYW1hbiBMaSAoMjAlKSBYaWFuZ3BpbmcgWmhvdSAoMjAlKSoqOiANCg0KIyMjIyBTYW1wbGUgU2VsZWN0aW9uIEJpYXMNCg0KSW4gdGVybXMgb2Ygc2FtcGxlIHNlbGVjdGlvbiwgd2UgY2hvb3NlIGZpcnN0LXRpZXIsIG5ldywgZmlyc3QtdGllciwgc2Vjb25kLXRpZXIsIGFuZCB0aGlyZC10aWVyIGNpdGllcyBpbiBDaGluYSBhcyBvdXIgdGFyZ2V0IGNpdGllcywgYW5kIHRoZW4gdXNlIHN0cmF0aWZpZWQgc2FtcGxpbmcgdG8gc2V0IG91ciB0cmVhdG1lbnQgYW5kIGNvbnRyb2wgZ3JvdXAuIEJ1dCBjb25zdW1lcnMgaW4gb2ZmbGluZSBzdG9yZXMgYXJlIGVudGlyZWx5IHJhbmRvbSwgYW5kIHRoZXJlIGlzIG5vIGd1YXJhbnRlZSB0aGF0IHRoZXkgY292ZXIgYWxsIG9mIG91ciBmb3VyIGN1c3RvbWVyIGdyb3Vwcy4gVGhlcmVmb3JlLCB3ZSBhc3N1bWUgdGhlIGV4cGVyaW1lbnQgcHJvY2VzcyBhcyBhIGJsYWNrIGJveCBhbmQgdGFrZSB0aGUgcmFuZG9tbmVzcyBhcyBwYXJ0IG9mIHRoZSBtYXJrZXQuDQoNCiMjIyMgTGFjayBvZiBPbmxpbmUgQ2hhbm5lbHMNCg0KT25saW5lIHNhbGVzIGFjY291bnQgZm9yIGEgcmVsYXRpdmVseSBsYXJnZSBwYXJ0IG9mIE5lc2NhZsOpLiBTdGlsbCwgc2luY2UgaXQgaXMgaGFyZCB0byBzZXQgdGhlIGNvbnRyb2wgZ3JvdXAgb25saW5lIGFuZCBpdCB3aWxsIGJlIGEgc2VwYXJhdGUgZXhwZXJpbWVudCB0byB0ZXN0IG9ubGluZSBjaGFubmVscywgd2Ugb25seSBjb25zaWRlciBvZmZsaW5lIGNoYW5uZWxzIGluIHRoaXMgZXhwZXJpbWVudC4gV2Ugd2lsbCB1c2UgaGlzdG9yaWNhbCBzYWxlcyBkYXRhIGJhc2VkIG9uIHRoZSBwcm9wb3J0aW9uIG9mIG9ubGluZSBhbmQgb2ZmbGluZSBjaGFubmVscyB0byBwcmVkaWN0IGFuZCBzdXBwbGVtZW50IG9ubGluZSBzYWxlcy4NCg0KIyMjIyBMb25nIEV4cGVyaW1lbnQgUGVyaW9kDQoNCkNvbnNpZGVyaW5nIHRoZSBzYWxlcyBjeWNsZSBhbmQgc2Vhc29uYWwgZWZmZWN0IG9mIGNvZmZlZSBwcm9kdWN0cywgd2Ugc2V0IHRoZSBleHBlcmltZW50IHBlcmlvZCBhcyBvbmUgeWVhci4gVGhlIGxvbmcgcGVyaW9kIG1heSBhbGxvdyB0aGUgY29tcGV0aXRvciB0byBsYXVuY2ggbmV3IHByb2R1Y3RzIGZpcnN0IGFuZCB0YWtlIHRoZSBsZWFkIGluIHRoZSBtYXJrZXQuIEJ1dCB3ZSB3aWxsIGNvbGxlY3QgYW5kIHRlc3QgdGhlIGRhdGEgZWFjaCBtb250aCB0byBtb25pdG9yIHRoZSByZWFsLXRpbWUgY2hhbmdlIG9mIHNhbGVzIGFuZCBkcmF3IGNvbmNsdXNpb25zIGluIGFuIGVmZmVjdGl2ZSBzaG9ydGVyIHBlcmlvZC4NCg0KIyMjIyBBY2N1cmFjeSBvZiBEYXRhIENvbGxlY3Rpb24NCg0KU2FsZXMgZGF0YSBvZiBvZmZsaW5lIHN0b3JlcyB1c3VhbGx5IGFyZSBjb2xsZWN0ZWQgYnkgcmVjb3JkcyBvZiB0aGUgY2FzaCByZWdpc3RlciBhbmQgbWFudWFsIGFnZ3JlZ2F0aW9uLiBUaGVyZSBtYXkgYmUgYSBodW1hbiBlcnJvciBkdXJpbmcgdGhlIHByb2Nlc3MuIFRoZXJlZm9yZSwgd2UgY2FuIGluY3JlYXNlIHRoZSBmcmVxdWVuY3kgYW5kIHJlZHVjZSB0aGUgdGltZSBnYXAgb2YgY29sbGVjdGluZyBkYXRhIHRvIGxvd2VyIHRoZSByaXNrIG9mIGVycm9yIGFuZCBlbnN1cmUgZGF0YSBhY2N1cmFjeSB0aHJvdWdoIGRhdGEgcHJvb2ZyZWFkaW5nIGluIGRpZmZlcmVudCBwZXJpb2RzLg0KDQojIyMjIExvY2F0aW9uIG9uIHRoZSBzaGVsZg0KDQpFYWNoIHJldGFpbCBzdG9yZSBhbmQgc3VwZXJtYXJrZXQgaGF2ZSB0aGVpciBvd24gd2F5IG9mIGFycmFuZ2luZyBnb29kcy4gVGhlIGxvY2F0aW9uIG9mIHRoZSBjb25jZW50cmF0ZWQgY29mZmVlIHBvZHMgb24gdGhlIHNoZWx2ZXMgaXMgaW1wb3J0YW50LCBhbmQgaXQgd291bGQgaW1wYWN0IHRoZSBzYWxlcyBvZiB0aGlzIHByb2R1Y3QuIEl0IGlzIGltcG9zc2libGUgdG8gcmVxdWlyZSBlYWNoIHN0b3JlIGFuZCBzdXBlcm1hcmtldCB0byBwbGFjZSB0aGUgcG9kcyBpbiB0aGUgc2FtZSBsb2NhdGlvbi4gVGhlcmVmb3JlLCB0aGUgbG9jYXRpb24gb24gdGhlIHNoZWx2ZXMgd291bGQgY2F1c2UgYmlhcy4NCg0KIyMjIyBQYW5kZW1pYw0KDQpUaGUgQ09WSUQtMTkgcGFuZGVtaWMgaGFkIGEgc2lnbmlmaWNhbnQgaW5mbHVlbmNlIG9uIG91ciBzb2NpZXR5LiBJbiBDaGluYSwgdGhleSBoYXZlIGEgc3RyaWN0IHN0cmF0ZWd5IGRlYWxpbmcgd2l0aCB0aGUgcGFuZGVtaWMgYnJlYWtvdXQuIEZvciBleGFtcGxlLCB3aGVuZXZlciBhIGNpdHkgaGFzIGluY3JlYXNpbmcgY2FzZXMsIHRoZSBDaGluZXNlIGdvdmVybm1lbnQgbWF5IHNodXQgZG93biB0aGUgZW50aXJlIGNpdHkgYW5kIHJlcXVpcmUgZXZlcnkgY2l0aXplbiB0byBzdGF5IGF0IGhvbWUuIE1lYW53aGlsZSwgZmFjaWxpdGllcyBzdWNoIGFzIHN1cGVybWFya2V0cyBtYXkgY2xvc2UgYXMgd2VsbC4gVGhlcmVmb3JlLCBpdCBjYW4gaGF2ZSBhIG1hc3NpdmUgaW5mbHVlbmNlIG9uIHNhbGVzLg0KDQojIyMjIENvbXBldGl0b3JzDQoNCk1hbnkgY29tcGV0aXRvcnMgbWFrZSBzaW1pbGFyIHByb2R1Y3RzIG9mIGluc3RhbnQgY29mZmVlIGluIENoaW5hLiBUaGVyZWZvcmUsIGFjdGlvbnMgZnJvbSBjb21wZXRpdG9ycyBzdWNoIGFzIGxhdW5jaGluZyBuZXcgcHJvZHVjdHMsIHByb21vdGlvbiwgYWR2ZXJ0aXNpbmcgd291bGQgaW1wYWN0IHRoZSBzYWxlcyBvZiBvdXIgcHJvZHVjdC4gU2luY2UgaXQgaXMgaW1wb3NzaWJsZSB0byBjb250cm9sIGNvbXBldGl0b3JzLCBpdCBjb3VsZCBjYXVzZSBhIGJpYXMuDQoNCg0KIyMgUGFydCAyOiAgU2ltdWxhdGVkIFN0dWRpZXMNCg0KKipNaW5naGFvIER1ICgyMCUpIEhhb2h1YSBMdSAoMjAlKSBGZW5neXVhbiBUaWFuICgyMCUpIEppYW1hbiBMaSAoMjAlKSBYaWFuZ3BpbmcgWmhvdSAoMjAlKSoqOiANCg0KIyMjIEluaXQgcGVyYW1ldGVycyANCg0KVGhlIGZpcnN0IHN0ZXAgd2FzIHRvIGNyZWF0ZSBhbiBlbXB0eSBkYXRhc2V0LiBCYXNlZCBvbiBvdXIgc2FtcGxlIHNlbGVjdGlvbiwgd2Ugc2ltdWxhdGVkIHRoZSBzYWxlcyBkYXRhIGluIDEwOCBjaXRpZXMsIGluY2x1ZGluZyAyIGZpcnN0LXRpZXIgY2l0aWVzLCAxNCBuZXcgZmlyc3QtdGllciBjaXRpZXMsIDI2IHNlY29uZC10aWVyIGNpdGllcywgYW5kIDY2IHRoaXJkLXRpZXIgY2l0aWVzLiBUaGUgY2l0aWVzIHdlcmUgZXZlbmx5IHNwbGl0IGludG8gY29udHJvbCBhbmQgdHJlYXRtZW50IGdyb3Vwcy4gVGhlbiwgd2Ugc2V0IG1lYW4gYW5kIHN0YW5kYXJkIGRldmlhdGlvbiBzY2FsZXMgZm9yIGNpdHkgdGllcnMgYmFzZWQgb24gdGhlIG51bWJlciBvZiBjb2ZmZWUgZW50ZXJwcmlzZXMgaW4gZWFjaCBjaXR5LiBBY2NvcmRpbmcgdG8gYSByZXBvcnQgZnJvbSBQaW50dSwgd2UgY2FsY3VsYXRlZCB0aGUgYXZlcmFnZSBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uIG9mIGNvZmZlZSBzaG9wIG51bWJlcnMgaW4gZWFjaCBjaXR5IGFuZCB0aGVuIHVzZWQgdGhvc2UgbnVtYmVycyB0byBkZWNpZGUgdGhlIHNpemUgb2YgdGhlIHZhcmlvdXMgdGllcnMuDQoNCg0KYGBge3J9DQoNCm4gPC0gMTA4DQoNCmNpdHlDbGFzcyA8LSBjKA0KICByZXAoIkZpcnN0IiwgMiksDQogIHJlcCgiTmV3LUZpcnN0IiwgMTQpLCANCiAgcmVwKCJTZWNlbmQiLCAyNiksIA0KICByZXAoIlRoaXJkIiwgNjYpKQ0KDQpjaXR5Q2xhc3NOdW0gPC0gYygNCiAgcmVwKDAsIDIpLA0KICByZXAoMSwgMTQpLCANCiAgcmVwKDIsIDI2KSwgDQogIHJlcCgzLCA2NikpDQoNCmdyb3VwIDwtIHJlcChjKCJUcmVhdG1lbnQiLCJDb250cm9sIiksIG4vMikNCg0KZW1wdHlEYXRhIDwtIGRhdGEuZnJhbWUoR3JvdXAgPSBncm91cCwgQ2l0eV9UaWVyID0gY2l0eUNsYXNzLCBDaXR5X1RpZXJfTnVtID0gY2l0eUNsYXNzTnVtKQ0KDQp0MUNvZmZlZVNob3BzIDwtIGMoMTI5NywgMjI3OCwgMTcyNSwgMjM3NykNCm50MUNvZmZlZVNob3BzIDwtIGMoMTg2NywgMTI1MywgMTMyNywgOTgzLCA4MzQsIDEwODYsIDEwNTQsIDEzODEpDQp0MkNvZmZlZVNob3BzIDwtIGMoMTA5OSwgMjQ0LCA0OTcsIDU1NiwgMzM5LCAyMjgsIDQ4MywgMzI1KQ0KdDNDb2ZmZWVTaG9wcyA8LSBjKDE0NiwgMjU4LCAxODQsIDIxNiwgMTI3LCA1OSwgMTQ5LCA4NikNCg0KdDFNIDwtIG1lYW4odDFDb2ZmZWVTaG9wcykNCnQxU0QgPC0gc2QodDFDb2ZmZWVTaG9wcykNCm50MU0gPC0gbWVhbihudDFDb2ZmZWVTaG9wcykNCm50MVNEIDwtIHNkKG50MUNvZmZlZVNob3BzKQ0KdDJNIDwtIG1lYW4odDJDb2ZmZWVTaG9wcykNCnQyU0QgPC0gc2QodDJDb2ZmZWVTaG9wcykNCnQzTSA8LSBtZWFuKHQzQ29mZmVlU2hvcHMpDQp0M1NEIDwtIHNkKHQzQ29mZmVlU2hvcHMpDQoNCiMgU2FsZXMgbWVhbiBzY2FsZSBmb3IgY2l0eSB0aWVycyANCnNhbGVzX01fZmFjdG9yIDwtIGModDFNLCBudDFNLCB0Mk0sIHQzTSkgLyB0MU0NCg0KIyBTYWxlcyBTRCBzY2FsZSBmb3IgY2l0eSB0aWVycyANCnNhbGVzX1NEX2ZhY3RvciA8LSBjKHQxU0QsIG50MVNELCB0MlNELCB0M1NEKSAvIHQxU0QNCg0KYGBgDQoNCiMjIyBIZWxwZXIgRnVuY3Rpb25zIA0KDQpUaGUgc2Vjb25kIHN0ZXAgd2FzIHRvIGNyZWF0ZSBmb3VyIHNpbXVsYXRpb24gYW5kIGV2YWx1YXRpb24gZnVuY3Rpb25zLiBUaGUgZmlyc3Qgb25lIGlzIGEgZnVuY3Rpb24gdGhhdCBjb21wdXRlcyBhIHNhbGVzIHZhbHVlIGJhc2VkIG9uIGEgZGF0YSBmcmFtZeKAmXMgbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uLiBTYWxlcyBhcmUgY2FsY3VsYXRlZCB1c2luZyBkZiwgbWVhbiwgc3RhbmRhcmQgZGV2aWF0aW9uLCBzYWxlc19NX2ZhY3RvciwgYW5kIHNhbGVzX1NEX2ZhY3Rvci4NCg0KVGhlIHNlY29uZCBmdW5jdGlvbiBjcmVhdGVzIHBsb3RzIGZvciB0aGUgZGF0YSBmcmFtZS4gVGhpcyBhbGxvd3MgdXMgdG8gb2JzZXJ2ZSB0aGUgdHJlbmQgYW5kIGRpZmZlcmVuY2VzIGluIHNhbGVzIGJldHdlZW4gZWFjaCBjaXR5Lg0KDQpBIHRoaXJkIGZ1bmN0aW9uIGNhbGN1bGF0ZXMgdGhlIGF2ZXJhZ2Ugc2FsZXMgcmVzdWx0cyBmcm9tIHRoZSB0ZXN0LiBGb3IgZWFjaCBjaXR5LCB3ZSBncm91cCB0aGVtIGludG8gIkNvbnRyb2wiIG9yICJUcmVhdG1lbnQiIGNpdGllcy4gVXNpbmcgdGhlIHQtdGVzdCByZXN1bHQsIHdlIHdpbGwgc2V0IHRoZSB1cHBlciBhbmQgbG93ZXIgYm91bmRzIGJhc2VkIG9uIHRoZSBjb2VmZmljaWVudC4gRm9yIGNvbXBhcmlzb24sIHdlIGxpc3QgdGhlIGVmZmVjdCwgbG93ZXIgYm91bmQsIHVwcGVyIGJvdW5kLCBhbmQgcC12YWx1ZSBpbiB0aGUgcmVzdWx0Lg0KDQpUaGUgZm91cnRoIGZ1bmN0aW9uIHV0aWxpemVzIHRoZSBnZW5lcmF0ZVNhbGVzIGZ1bmN0aW9uIHRvIGdlbmVyYXRlIHNhbGVzIGRhdGEgZm9yIHRyZWF0bWVudCBhbmQgY29udHJvbCBncm91cHMuIFdlIHNldCB0aGUgYmFzZWxpbmUgYXMgZm9sbG93czogbWVhbiBvZiB0cmVhdG1lbnQgZ3JvdXAgPSAxMDAsIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdHJlYXRtZW50IGdyb3VwID0gMTAsIG1lYW4gb2YgdGhlIGNvbnRyb2wgZ3JvdXAgaXMgOTAsIHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIGNvbnRyb2wgZ3JvdXAgaXMgNS4NCg0KDQpgYGB7cn0NCg0KIyBmdW5jdGlvbiB0byBnZW5lcmF0ZSBzYWxlcyB2YWx1ZSBmcm9tIG1lYW4gYW5kIFNEIGZvciBhIGRhdGFmcmFtZQ0KZ2VuZXJhdGVTYWxlcyA8LQ0KICBmdW5jdGlvbihkZiwgDQogICAgICAgICAgIG1lYW4sDQogICAgICAgICAgIHNkLA0KICAgICAgICAgICBTTUYgPSBzYWxlc19NX2ZhY3RvciwNCiAgICAgICAgICAgU1NERiA9IHNhbGVzX1NEX2ZhY3Rvcikgew0KICAgIG91dCA8LSBkZiAlPiUNCiAgICAgIHJvd3dpc2UoKSAlPiUNCiAgICAgIG11dGF0ZShTYWxlcyA9IHJub3JtKDEsIG1lYW4gPSBtZWFuICogU01GW0NpdHlfVGllcl9OdW0gKyAxXSwgc2QgPSBzZCAqIFNTREZbQ2l0eV9UaWVyX051bSArIDFdKSkNCiAgICByZXR1cm4ob3V0KSANCiAgfQ0KDQojIGZ1bmN0aW9uIHRvIG1ha2UgcGxvdHMgZm9yIGRhdGFmcmFtZSANCnBsb3RTYWxlcyA8LSBmdW5jdGlvbihkZikgew0KICBwMSA8LSBkZiAlPiUgZ2dwbG90KCkgKyANCiAgICBnZW9tX2RlbnNpdHkoYWVzKFNhbGVzLCBjb2xvciA9IEdyb3VwKSkgDQogIHAxIDwtIHAxICU+JSBnZ3Bsb3RseSgpDQogIHAyIDwtIGRmICU+JSBnZ3Bsb3QoKSArIA0KICAgIGdlb21fZGVuc2l0eShhZXMoU2FsZXMsIGNvbG9yID0gQ2l0eV9UaWVyKSkgKyANCiAgICBmYWNldF93cmFwKH5Hcm91cCkNCiAgcDIgPC0gcDIgJT4lIGdncGxvdGx5KCkNCiAgcDMgPC0gZGYgJT4lIA0KICAgIGdyb3VwX2J5KEdyb3VwLCBDaXR5X1RpZXIpICU+JSANCiAgICBzdW1tYXJpemUoQXZnU2FsZXMgPSBtZWFuKFNhbGVzKSkgJT4lIA0KICAgIHVuZ3JvdXAoKSAlPiUgDQogICAgZ2dwbG90KCkgKyANCiAgICBnZW9tX2NvbChhZXMoQXZnU2FsZXMsIENpdHlfVGllciwgZmlsbCA9IEdyb3VwKSwgcG9zaXRpb24gPSAiZG9kZ2UiKQ0KICBwMyA8LSBwMyAlPiUgZ2dwbG90bHkoKQ0KICANCiAgbGlzdChwMSwgcDIsIHAzKQ0KfQ0KDQoNCiMgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIFNhbGVzIG1lYW4gdHRlc3QgcmVzdWx0cyBmcm9tIGEgZGF0YWZyYW1lIA0KYW5hbHl6ZURhdGEgPC0gZnVuY3Rpb24oZGYpIHsNCiAgdFRlc3QgPC0NCiAgICB0LnRlc3QoDQogICAgICBkZiAlPiUgZmlsdGVyKEdyb3VwID09ICJUcmVhdG1lbnQiKSAlPiUgc2VsZWN0KFNhbGVzKSwNCiAgICAgIGRmICU+JSBmaWx0ZXIoR3JvdXAgPT0gIkNvbnRyb2wiKSAlPiUgc2VsZWN0KFNhbGVzKQ0KICAgICkNCiAgdGhlLmVmZmVjdCA8LSB0VGVzdCRlc3RpbWF0ZVtbMV1dIC0gdFRlc3QkZXN0aW1hdGVbWzJdXQ0KICBsb3dlci5ib3VuZCA8LSB0VGVzdCRjb25mLmludFsxXQ0KICB1cHBlci5ib3VuZCA8LSB0VGVzdCRjb25mLmludFsyXQ0KICBwIDwtIHRUZXN0JHAudmFsdWUNCiAgcmVzdWx0IDwtIGxpc3QoZWZmZWN0ID0gdGhlLmVmZmVjdCwgbG93ZXJfY2kgPSBsb3dlci5ib3VuZCwgdXBwZXJfY2kgPSB1cHBlci5ib3VuZCwgcCA9IHApDQogIA0KICByZXR1cm4ocmVzdWx0KQ0KfQ0KDQojIGZ1bmN0aW9uIHRvIHVzZSBgZ2VuZXJhdGVTYWxlc2AgbWFrZSBzYWxlcyBkYXRhIGZvciB0cmVhdG1lbnQgYW5kIGNvbnRyb2wgZ3JvdXAgDQpzaW1TYWxlc0RGIDwtDQogIGZ1bmN0aW9uKERGID0gZW1wdHlEYXRhLA0KICAgICAgICAgICB0cmVhdE0gPSAxMDAsDQogICAgICAgICAgIHRyZWF0U0QgPSAxMCwNCiAgICAgICAgICAgY3RybE0gPSA5MCwNCiAgICAgICAgICAgY3RybFNEID0gNSwNCiAgICAgICAgICAgU01GID0gc2FsZXNfTV9mYWN0b3IsDQogICAgICAgICAgIFNTREYgPSBzYWxlc19TRF9mYWN0b3IpIHsNCiAgICB0cmVhdG1lbnREYXRhIDwtDQogICAgICBERiAlPiUgZmlsdGVyKEdyb3VwID09ICJUcmVhdG1lbnQiKSAlPiUgZ2VuZXJhdGVTYWxlcyh0cmVhdE0sIHRyZWF0U0QsIFNNRiwgU1NERikNCiAgICBjb250cm9sRGF0YSA8LQ0KICAgICAgREYgJT4lIGZpbHRlcihHcm91cCA9PSAiQ29udHJvbCIpICU+JSBnZW5lcmF0ZVNhbGVzKGN0cmxNLCBjdHJsU0QsIFNNRiwgU1NERikNCiAgICANCiAgICBzaW0uZGF0YSA8LSB0cmVhdG1lbnREYXRhICU+JSByYmluZChjb250cm9sRGF0YSkgJT4lIHVuZ3JvdXAoKQ0KICAgIA0KICAgIHJldHVybihzaW0uZGF0YSkNCiAgfQ0KYGBgDQoNCiMjIyBFeHBsb3JlIHNpbXVsYXRlZCBkYXRhIA0KDQojIyMjIFNpbmdsZSBTaW11bGF0aW9uDQoNCldlIGZpbmFsaXplZCB0aGUgc2ltdWxhdGVkIGRhdGEgYW5kIHBsb3R0ZWQgdGhlIGRhdGEgdG8gbWFrZSBzdXJlIGFsbCBmdW5jdGlvbnMgd29ya2VkLg0KDQoNCmBgYHtyIHBhZ2VkLnByaW50PVRSVUV9DQojIG1ha2Ugc3VyZSBhbGwgZnVuY3Rpb24gd29ya3MgDQoNCnNpbS5kYXRhIDwtIHNpbVNhbGVzREYoZW1wdHlEYXRhLCAxMTAsIDEwLCAxMDAsIDEwLCBzYWxlc19NX2ZhY3Rvciwgc2FsZXNfU0RfZmFjdG9yKQ0KDQpzaW0uZGF0YQ0KDQpwbG90cyA8LSBwbG90U2FsZXMoc2ltLmRhdGEpDQoNCnBsb3RzW1sxXV0NCnBsb3RzW1syXV0NCnBsb3RzW1szXV0NCg0KYW5hbHl6ZURhdGEoc2ltLmRhdGEpDQpgYGANCg0KRmluYWxseSwgd2UgY29uc3RydWN0ZWQgYSBwb3dlciB0LXRlc3QgdG8gdGVzdCB0aGUgaWRlYWwgZWZmZWN0IHNpemUuIEFzc3VtZSB0aGUgcG93ZXIgb2YgdGhlIHRlc3QgaXMgMC45LCBhY2NvcmRpbmcgdG8gdGhlIHRlc3QgcmVzdWx0LCB0aGUgZWZmZWN0IHNpemUgc2hvdWxkIGJlIDYyLiBCdXQgZHVlIHRvIHRoZSBsaW1pdGF0aW9uIG9mIHRoZSBzaXplIG9mIGNpdGllcywgd2UgYXJlIG5vdCBhYmxlIHRvIHJlYWNoIHRoZSBpZGVhbCBzYW1wbGUgc2l6ZS4gQnV0IHRoZSByZXN1bHQgY2FuIHByb3ZpZGUgdXMgYSByZWZlcmVuY2UgZm9yIGZ1cnRoZXIgYW5hbHlzaXMuDQoNCg0KYGBge3J9DQpwd3JUZXN0IDwtIHB3ci50LnRlc3QobiA9IG4vMiwgcG93ZXIgPSAwLjkpDQpwd3JUZXN0DQpgYGANCg0KIyMjIyBTaW5nbGUgRXhwZXJpbWVudCANCg0KRm9yIGV4cGVyaW1lbnQsIHdlIGZpcnN0IHNldCB0aGUgbnVtYmVyIG9mIHNpbXVsYXRpb24gPSAxMDAwLCBtZWFuIG9mIHRoZSBjb250cm9sIGdyb3VwID0gMTAwLCBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIGNvbnRyb2wgZ3JvdXAgPSAxMCwgZWZmZWN0IHNpemUgPSA1NSwgc2lnbmlmaWNhbmNlIGxldmVsID0gMC4wNS4gVGhlbiB3ZSBydW4gdGhlIHNpbXVsYXRpb24gYmFzZWQgb24gdGhlc2UgcGFyYW1ldGVycy4gVXNpbmcgdGhlIHQtdGVzdCwgd2UgZ290IHRoZSByZXN1bHQgb2YgdGhlIHNpbXVsYXRpb246IFRoZSBQb3dlciBvZiB0aGUgdGVzdCB3aXRoIGFuIGVmZmVjdGl2ZSBzaXplIG9mIDU1ICBhbmQgYSBzaWduaWZpY2FudCBsZXZlbCBvZiAgMC4wNSBpcyAwLjc5Ni4NCg0KDQpgYGB7cn0NCiMgTnVtYmVyIG9mIHNpbXVsYXRpb25zIA0KQiA8LSAxMDAwIA0KDQpFeHBlcmltZW50IDwtIDE6QiANCg0KREZMaXN0IDwtIGMoKQ0KDQpjdHJsTWVhbiA8LSAxMDANCnN0ZERpdiA8LSAxMA0KZWZmZWN0U2l6ZSA8LSA1NQ0Kc2lnTGV2ZWwgPC0gMC4wNQ0KDQojIHJ1biBzaW11bGF0aW9ucw0KcGIgPC0gcHJvZ3Jlc3NfYmFyJG5ldyh0b3RhbCA9IEIpDQpmb3IgKGkgaW4gRXhwZXJpbWVudCkgew0KICBwYiR0aWNrKCkNCiAgREZMaXN0W1tpXV0gPC0NCiAgICBlbXB0eURhdGEgJT4lIHNpbVNhbGVzREYoY3RybE1lYW4gKyBlZmZlY3RTaXplLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGREaXYsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0cmxNZWFuLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGREaXYsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbGVzX01fZmFjdG9yLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYWxlc19TRF9mYWN0b3IpDQp9DQoNCmV4cFNpbURhdGEgPC0gdGliYmxlKEV4cGVyaW1lbnQgPSBFeHBlcmltZW50LCBERiA9IERGTGlzdCkNCg0KIyBnZXQgdC10ZXN0IHJlc3VsdCBmb3Igc2ltdWxhdGlvbiANCnNpbURhdGFBbmFseXplZCA8LSBleHBTaW1EYXRhICU+JSBtdXRhdGUoUmVzdWx0ID0gbWFwKERGLCBhbmFseXplRGF0YSkpICU+JSB1bm5lc3Rfd2lkZXIoUmVzdWx0KQ0KDQpwcmludChwYXN0ZSgiUG93ZXIgd2l0aCBhbiBlZmZlY3RpdmUgc2l6ZSBvZiAiLCBlZmZlY3RTaXplLCAiIGFuZCBhIHNpZ25pZmljYW50IGxldmVsIG9mICIsIHNpZ0xldmVsLCIgOiAiLCBtZWFuKHNpbURhdGFBbmFseXplZCRwIDwgc2lnTGV2ZWwpKSkNCnByaW50KHBhc3RlKCJBdmVyYWdlIFAtdmFsdWUiLG1lYW4oc2ltRGF0YUFuYWx5emVkJHApKSkNCnN1bW1hcnkoc2ltRGF0YUFuYWx5emVkJGVmZmVjdCkNCnN1bW1hcnkoc2ltRGF0YUFuYWx5emVkJGxvd2VyX2NpKQ0Kc3VtbWFyeShzaW1EYXRhQW5hbHl6ZWQkdXBwZXJfY2kpDQoNCmBgYA0KDQojIyMjIEV4cGVyaW1lbnRzIGZvciBkaWZmZXJlbnQgZWZmZWN0aXZlIHNpemUNCg0KTmV4dCwgd2UgZGVmaW5lZCB0aGUgZWZmZWN0aXZlIHNpemUgcmFuZ2UgdG8gYmUgdGVzdGVkIGFzIFszMCwgNzBdLiBGb3IgZWFjaCBlZmZlY3RpdmUgc2l6ZSwgd2UgcnVuIGFuIGV4cGVyaW1lbnQgb2YgMTAwMCBzaW11bGF0aW9ucyB0byBkZXRlcm1pbmUgdGhlIHBvd2VyLiBXZSBhbHNvIGdvdCB0aGUgZWZmZWN0aXZlIHNpemUgdGhyZXNob2xkIGdpdmVuIGEgc2lnbmlmaWNhbnQgbGV2ZWwuDQoNCg0KYGBge3IgcGFnZWQucHJpbnQ9VFJVRX0NCiMgZGVmaW5lIGVmZmVjdGl2ZSBzaXplIHJhbmdlIHRvIGJlIHRlc3RlZA0KZVNpemUgPC0gc2VxKDMwLCA3MCkNCg0KIyBmb3IgZWFjaCBlZmZlY3RpdmUgc2l6ZSBydW4gb25lIGV4cGVyaW1lbnQgb2YgMTAwMCBzaW11bGF0aW9ucyB0byBkZXRlcm1pbmUgdGhlIHBvd2VyDQpyZXN1bHQgPC0NCiAgZm9yZWFjaCh4ID0gZVNpemUsDQogICAgICAgICAgLmNvbWJpbmUgPSByYmluZCwNCiAgICAgICAgICAucGFja2FnZXMgPSBjKCJ0aWR5dmVyc2UiKSkgJWRvcGFyJSB7DQogICAgICAgICAgICBCIDwtIDEwMDANCg0KICAgICAgICAgICAgRXhwZXJpbWVudCA8LSAxOkINCg0KICAgICAgICAgICAgREZMaXN0IDwtIGMoKQ0KDQogICAgICAgICAgICBjdHJsTWVhbiA8LSAxMDANCiAgICAgICAgICAgIHN0ZERpdiA8LSAxMA0KICAgICAgICAgICAgZWZmZWN0U2l6ZSA8LSB4DQogICAgICAgICAgICBzaWdMZXZlbCA8LSAwLjA1DQoNCiAgICAgICAgICAgIGZvciAoaSBpbiBFeHBlcmltZW50KSB7DQogICAgICAgICAgICAgIERGTGlzdFtbaV1dIDwtDQogICAgICAgICAgICAgICAgZW1wdHlEYXRhICU+JSBzaW1TYWxlc0RGKGN0cmxNZWFuICsgZWZmZWN0U2l6ZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkRGl2LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHJsTWVhbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkRGl2LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYWxlc19NX2ZhY3RvciwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FsZXNfU0RfZmFjdG9yKQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBleHBTaW1EYXRhIDwtIHRpYmJsZShFeHBlcmltZW50ID0gRXhwZXJpbWVudCwgREYgPSBERkxpc3QpDQoNCiAgICAgICAgICAgIHNpbURhdGFBbmFseXplZCA8LQ0KICAgICAgICAgICAgICBleHBTaW1EYXRhICU+JSBtdXRhdGUoUmVzdWx0ID0gbWFwKERGLCBhbmFseXplRGF0YSkpICU+JSB1bm5lc3Rfd2lkZXIoUmVzdWx0KQ0KICAgICAgICAgICAgZVAgPC0gbWVhbihzaW1EYXRhQW5hbHl6ZWQkcCA8IHNpZ0xldmVsKQ0KICAgICAgICAgICAgZUFwIDwtIG1lYW4oc2ltRGF0YUFuYWx5emVkJHApDQogICAgICAgICAgICBlRiA8LSBtZWFuKHNpbURhdGFBbmFseXplZCRlZmZlY3QpDQogICAgICAgICAgICBlVSA8LSBtZWFuKHNpbURhdGFBbmFseXplZCR1cHBlcl9jaSkNCiAgICAgICAgICAgIGVMIDwtIG1lYW4oc2ltRGF0YUFuYWx5emVkJGxvd2VyX2NpKQ0KDQogICAgICAgICAgICBjKHgsIGVBcCwgZVAsIGVGLCBlTCwgZVUpDQogICAgICAgICAgfQ0KDQplZmZlY3RQb3dlciA8LSBhcy5kYXRhLmZyYW1lKHJlc3VsdCkgJT4lIGFzX3RpYmJsZSgpDQoNCmNvbG5hbWVzKGVmZmVjdFBvd2VyKSA8LSBjKCJlU2l6ZSIsICJlQXZnUCIsICJlUG93IiwgImVFZnMiLCAiZUxvdyIsICJlVXAiKQ0KDQojIGdpdmVuIGEgc2lnbmlmaWNhbnQgbGV2ZWwgc2VlIHRoZSBlZmZlY3RpdmUgc2l6ZSB0aHJlc2hvbGQNCmVmZmVjdFBvd2VyIDwtIGVmZmVjdFBvd2VyICU+JSBtdXRhdGUocGFzc2VkID0gaWZlbHNlKGVQb3cgPCAoMS1zaWdMZXZlbCksIEYsIFQpKQ0KDQplZmZlY3RQb3dlcg0KYGBgDQoNClRvIGV2YWx1YXRlIHRoZSBwb3dlciBvZiB0aGUgdGVzdCwgd2UgYnVpbHQgYSBwbG90IHRvIHNob3cgdGhlIGV4cGVyaW1lbnQgcG93ZXIgYmFzZWQgb24gZGlmZmVyZW50IGVmZmVjdCBzaXplcy4gV2Ugc2V0IGEgYmFzZWxpbmUgb2YgcG93ZXIgYXMgMC45NS4gVGhlIHBsb3Qgc2hvd3MgdGhhdCB3aGVuIHRoZSBlZmZlY3Qgc2l6ZSBpcyBvdmVyIDYwLCB0aGUgcG93ZXIgdGVzdCB3b3VsZCBzdXJwYXNzIHRoZSBiYXNlbGluZSwgd2hpY2ggbWVhbnMgdGhhdCBhdCB0aGlzIGxldmVsLCB0aGUgcHJvYmFiaWxpdHkgb2Ygb3VyIHJlc3VsdCBpcyBsYXJnZXIgdGhhbiA5NSUuDQoNCmBgYHtyfQ0KIyBwbG90IGVmZmVjdGl2ZSBzaXplIHZzIGV4cGVyaW1lbnQgcG93ZXINCmZpZyA8LSBlZmZlY3RQb3dlciAlPiUgZ2dwbG90KCkgKw0KICBnZW9tX3BvaW50KGFlcyhlU2l6ZSwgZVBvdykpICsNCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IDEgLSBzaWdMZXZlbCkpDQoNCmZpZyAlPiUgZ2dwbG90bHkoKQ0KYGBgDQoNCkZ1cnRoZXIsIHdlIHBsb3R0ZWQgdGhlIHRyZW5kIG9mIHAtdmFsdWUgd2l0aCB0aGUgY2hhbmdlIG9mIGVmZmVjdCBzaXplLiBBcyBzaG93biBpbiB0aGUgZ3JhcGgsIHdoZW4gdGhlIGVmZmVjdCBzaXplIGlzIGxhcmdlciB0aGFuIDYwLCB0aGUgYXZlcmFnZSBwLXZhbHVlIHJlZHVjZXMgdG8gbGVzcyB0aGFuIDAuMDUuIEEgcC12YWx1ZSBsZXNzIHRoYW4gMC4wNSBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LiBJdCBpbmRpY2F0ZXMgc3Ryb25nIGV2aWRlbmNlIGFnYWluc3QgdGhlIG51bGwgaHlwb3RoZXNpcywgYXMgdGhlcmUgaXMgbGVzcyB0aGFuIGEgNSUgcHJvYmFiaWxpdHkgdGhlIG51bGwgaXMgY29ycmVjdC4NCg0KYGBge3J9DQojIHBsb3QgQXZnIFAgdnMgZXhwZXJpbWVudCBwb3dlcg0KZmlnIDwtIGVmZmVjdFBvd2VyICU+JSBnZ3Bsb3QoKSArDQogIGdlb21fcG9pbnQoYWVzKGVTaXplLCBlQXZnUCkpICsNCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IHNpZ0xldmVsKSkNCg0KZmlnICU+JSBnZ3Bsb3RseSgpDQpgYGANCg0KIyMjIyBGYW5jeSBQbG90cyANCg0KYGBge3J9DQoNCiNHcmFwaCBSZXNvbHV0aW9uIChtb3JlIGltcG9ydGFudCBmb3IgbW9yZSBjb21wbGV4IHNoYXBlcykNCmdyYXBoX3Jlc28gPC0gMC4wMQ0KDQojU2V0dXAgQXhpcw0KYXhpc194IDwtIHNlcShtaW4oZWZmZWN0UG93ZXIkZUF2Z1ApLCBtYXgoZWZmZWN0UG93ZXIkZUF2Z1ApLCBieSA9IGdyYXBoX3Jlc28pDQpheGlzX3kgPC0gc2VxKG1pbihlZmZlY3RQb3dlciRlUG93KSwgbWF4KGVmZmVjdFBvd2VyJGVQb3cpLCBieSA9IGdyYXBoX3Jlc28pDQoNCnNldC5zZWVkKDEyMykNCnJlZ01vZGVsIDwtIHN2bV9yYmYoY29zdCA9IDAuNSwgcmJmX3NpZ21hID0gMC44LCBtYXJnaW4gPSAwLjAxKSAlPiUNCiAgc2V0X2VuZ2luZSgia2VybmxhYiIpICU+JQ0KICBzZXRfbW9kZSgicmVncmVzc2lvbiIpICU+JQ0KICBmaXQoZVNpemUgfiBlQXZnUCArIGVQb3csIGRhdGEgPSBlZmZlY3RQb3dlcikNCg0KI1NhbXBsZSBwb2ludHMNCnh5IDwtIG1lc2hncmlkKHggPSBheGlzX3gsIHkgPSBheGlzX3kpDQp4eCA8LSB4eSRYDQp5eSA8LSB4eSRZDQpkaW1fdmFsIDwtIGRpbSh4eCkNCnh4MSA8LSBtYXRyaXgoeHgsIGxlbmd0aCh4eCksIDEpDQp5eTEgPC0gbWF0cml4KHl5LCBsZW5ndGgoeXkpLCAxKQ0KZmluYWwgPC0gY2JpbmQoeHgxLCB5eTEpDQpwcmVkIDwtIHJlZ01vZGVsICU+JSBwcmVkaWN0KGZpbmFsKQ0KDQpwcmVkIDwtIHByZWQkLnByZWQNCnByZWQgPC0gbWF0cml4KHByZWQsIGRpbV92YWxbMV0sIGRpbV92YWxbMl0pDQoNCiMgM0QgcGxvdCBmb3IgQXZlcmFnZSBQIHZzIGVmZmVjdGl2ZSBzaXplIENJIHZzIFBvd2VyDQplZmZlY3RQb3dlciAlPiUNCiAgcGxvdF9seSgNCiAgICB4ID0gfiBlQXZnUCwNCiAgICB5ID0gfiBlUG93LA0KICAgIHogPSB+IGVTaXplDQogICkgJT4lDQogIGFkZF9tYXJrZXJzKCkgJT4lDQogIGFkZF9zdXJmYWNlKHggPSBheGlzX3gsDQogICAgICAgICAgICAgIHkgPSBheGlzX3ksDQogICAgICAgICAgICAgIHogPSBwcmVkLA0KICAgICAgICAgICAgICB0eXBlID0gJ21lc2gzZCcpICU+JQ0KICBtYWtlX2l0X3NwaW4oKQ0KDQpgYGANCg0KYGBge3J9DQoNCiNHcmFwaCBSZXNvbHV0aW9uIChtb3JlIGltcG9ydGFudCBmb3IgbW9yZSBjb21wbGV4IHNoYXBlcykNCmdyYXBoX3Jlc28gPC0gMC4wMQ0KDQojU2V0dXAgQXhpcw0KYXhpc194IDwtIHNlcShtaW4oZWZmZWN0UG93ZXIkZVVwKSwgbWF4KGVmZmVjdFBvd2VyJGVVcCksIGJ5ID0gZ3JhcGhfcmVzbykNCmF4aXNfeSA8LSBzZXEobWluKGVmZmVjdFBvd2VyJGVMb3cpLCBtYXgoZWZmZWN0UG93ZXIkZUxvdyksIGJ5ID0gZ3JhcGhfcmVzbykNCg0Kc2V0LnNlZWQoMTIzKQ0KcmVnTW9kZWwgPC0gc3ZtX3JiZihjb3N0ID0gMC4yNSwgcmJmX3NpZ21hID0gMC4yKSAlPiUNCiAgc2V0X2VuZ2luZSgia2VybmxhYiIpICU+JQ0KICBzZXRfbW9kZSgicmVncmVzc2lvbiIpICU+JQ0KICBmaXQoZVBvdyB+IGVVcCArIGVMb3csIGRhdGEgPSBlZmZlY3RQb3dlcikNCg0KI1NhbXBsZSBwb2ludHMNCnh5IDwtIG1lc2hncmlkKHggPSBheGlzX3gsIHkgPSBheGlzX3kpDQp4eCA8LSB4eSRYDQp5eSA8LSB4eSRZDQpkaW1fdmFsIDwtIGRpbSh4eCkNCnh4MSA8LSBtYXRyaXgoeHgsIGxlbmd0aCh4eCksIDEpDQp5eTEgPC0gbWF0cml4KHl5LCBsZW5ndGgoeXkpLCAxKQ0KZmluYWwgPC0gY2JpbmQoeHgxLCB5eTEpDQpwcmVkIDwtIHJlZ01vZGVsICU+JSBwcmVkaWN0KGZpbmFsKQ0KDQpwcmVkIDwtIHByZWQkLnByZWQNCnByZWQgPC0gbWF0cml4KHByZWQsIGRpbV92YWxbMV0sIGRpbV92YWxbMl0pDQoNCiMgM0QgcGxvdCBmb3IgbG93ZXIgQ0kgdnMgdXBwZXIgQ0kgdnMgUG93ZXINCmVmZmVjdFBvd2VyICU+JQ0KICBwbG90X2x5KA0KICAgIHggPSB+IGVVcCwNCiAgICB5ID0gfiBlTG93LA0KICAgIHogPSB+IGVQb3csDQogICAgdGV4dCA9IH4gcGFzdGUoJ0VmZmVjdCBTaXplOiAnLCBlU2l6ZSkNCiAgKSAlPiUNCiAgYWRkX21hcmtlcnMoKSAlPiUNCiAgYWRkX3N1cmZhY2UoeCA9IGF4aXNfeCwNCiAgICAgICAgICAgICAgeSA9IGF4aXNfeSwNCiAgICAgICAgICAgICAgeiA9IHByZWQsDQogICAgICAgICAgICAgIHR5cGUgPSAnbWVzaDNkJykgJT4lDQogIG1ha2VfaXRfc3BpbigpDQoNCmBgYA0KDQoNCiMjIyBSZXNlYXJjaCBRdWVzdGlvbiAxOg0KDQojIyMjIFNjZW5hcmlvIDE6ICBObyBFZmZlY3QNCg0KKipNaW5naGFvIER1ICgyMCUpIEhhb2h1YSBMdSAoMjAlKSBGZW5neXVhbiBUaWFuICgyMCUpIEppYW1hbiBMaSAoMjAlKSBYaWFuZ3BpbmcgWmhvdSAoMjAlKSoqOiANCg0KV2lsbCB0aGUgbGF1bmNoIG9mIE5lc2NhZmUgY29uY2VudHJhdGVkIGNvZmZlZSBwb2RzIGluY3JlYXNlIE5lc2NhZmXigJlzIHNhbGVzIGluIHRoZSBDaGluZXNlIG1hcmtldD8NCg0KDQojIyMjIyBTaW11bGF0aW9uDQoNCmBgYHtyIHExX3NjZW5hcmlvMV9zaW11bGF0aW9ufQ0KIyBOdW1iZXIgb2Ygc2ltdWxhdGlvbnMNCkIgPC0gMTAwMA0KDQpFeHBlcmltZW50IDwtIDE6Qg0KDQpERkxpc3QgPC0gYygpDQoNCmN0cmxNZWFuIDwtIDEwMA0Kc3RkRGl2IDwtIDEwDQplZmZlY3RTaXplIDwtIDQwDQpzaWdMZXZlbCA8LSAwLjA1DQoNCiMgcnVuIHNpbXVsYXRpb25zDQpwYiA8LSBwcm9ncmVzc19iYXIkbmV3KHRvdGFsID0gQikNCmZvciAoaSBpbiBFeHBlcmltZW50KSB7DQogIHBiJHRpY2soKQ0KICBERkxpc3RbW2ldXSA8LQ0KICAgIGVtcHR5RGF0YSAlPiUgc2ltU2FsZXNERihjdHJsTWVhbiArIGVmZmVjdFNpemUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZERpdiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3RybE1lYW4sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZERpdiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FsZXNfTV9mYWN0b3IsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbGVzX1NEX2ZhY3RvcikNCn0NCg0KZXhwU2ltRGF0YSA8LSB0aWJibGUoRXhwZXJpbWVudCA9IEV4cGVyaW1lbnQsIERGID0gREZMaXN0KQ0KDQpgYGANCg0KDQojIyMjIyBBbmFseXNpcw0KDQpgYGB7ciBxMV9zY2VuYXJpbzFfYW5hbHlzaXN9DQoNCiMgZ2V0IHQtdGVzdCByZXN1bHQgZm9yIHNpbXVsYXRpb24NCnNpbURhdGFBbmFseXplZCA8LSBleHBTaW1EYXRhICU+JSBtdXRhdGUoUmVzdWx0ID0gbWFwKERGLCBhbmFseXplRGF0YSkpICU+JSB1bm5lc3Rfd2lkZXIoUmVzdWx0KQ0KDQpwcmludChwYXN0ZSgiUG93ZXIgd2l0aCBhbiBlZmZlY3RpdmUgc2l6ZSBvZiAiLCBlZmZlY3RTaXplLCAiIGFuZCBhIHNpZ25pZmljYW50IGxldmVsIG9mICIsIHNpZ0xldmVsLCIgOiAiLCBtZWFuKHNpbURhdGFBbmFseXplZCRwIDwgc2lnTGV2ZWwpKSkNCnByaW50KHBhc3RlKCJBdmVyYWdlIFAgdmFsdWU6ICIsIG1lYW4oc2ltRGF0YUFuYWx5emVkJHApKSkNCnN1bW1hcnkoc2ltRGF0YUFuYWx5emVkJGVmZmVjdCkNCnN1bW1hcnkoc2ltRGF0YUFuYWx5emVkJGxvd2VyX2NpKQ0Kc3VtbWFyeShzaW1EYXRhQW5hbHl6ZWQkdXBwZXJfY2kpDQpgYGANCg0KVGhlIHNpbXVsYXRpb24gcmVzdWx0IHNob3dzIGEgUC12YWx1ZSAoMC4xMDg2KSB0aGF0IGlzIGxhcmdlciB0aGFuIDUlLCB3aGljaCBpcyBub3Qgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4gVGhlcmVmb3JlLCB3ZSB3aWxsIGFjY2VwdCBvdXIgbnVsbCBoeXBvdGhlc2lzIHRoYXQgdGhlIGxhdW5jaCBvZiBOZXNjYWZlIGNvbmNlbnRyYXRlZCBjb2ZmZWUgcG9kcyB3aWxsIG5vdCBpbmNyZWFzZSBOZXNjYWZl4oCZcyBzYWxlcyBpbiB0aGUgQ2hpbmVzZSBtYXJrZXQuIFdlIHJlamVjdCBvdXIgYWx0ZXJuYXRpdmUgaHlwb3RoZXNpcyB0aGF0IHRoZSBsYXVuY2ggb2YgTmVzY2FmZSBjb25jZW50cmF0ZWQgY29mZmVlIHBvZHMgd2lsbCBpbmNyZWFzZSBOZXNjYWZl4oCZcyBzYWxlcyBpbiB0aGUgQ2hpbmVzZSBtYXJrZXQuIEluIHRoaXMgc2NlbmFyaW8sIHdlIHJlY29tbWVuZCBub3QgbGF1bmNoaW5nIHRoZSBOZXNjYWZlIGNvbmNlbnRyYXRlZCBjb2ZmZWUgcG9kcyBpbiB0aGUgQ2hpbmVzZSBtYXJrZXQgc2luY2UgaXQgd2lsbCBub3QgaW5jcmVhc2UgTmVzY2FmZeKAmXMgc2FsZXMuDQoNCg0KIyMjIyBTY2VuYXJpbyAyOiAgQW4gRXhwZWN0ZWQgRWZmZWN0DQoNCioqTWluZ2hhbyBEdSAoMjAlKSBIYW9odWEgTHUgKDIwJSkgRmVuZ3l1YW4gVGlhbiAoMjAlKSBKaWFtYW4gTGkgKDIwJSkgWGlhbmdwaW5nIFpob3UgKDIwJSkqKjogDQoNCg0KIyMjIyMgU2ltdWxhdGlvbg0KDQpgYGB7ciBxMV9zY2VuYXJpbzJfc2ltdWxhdGlvbn0NCiMgTnVtYmVyIG9mIHNpbXVsYXRpb25zDQpCIDwtIDEwMDANCg0KRXhwZXJpbWVudCA8LSAxOkINCg0KREZMaXN0IDwtIGMoKQ0KDQpjdHJsTWVhbiA8LSAxMDANCnN0ZERpdiA8LSAxMA0KZWZmZWN0U2l6ZSA8LSA2MA0Kc2lnTGV2ZWwgPC0gMC4wNQ0KDQojIHJ1biBzaW11bGF0aW9ucw0KcGIgPC0gcHJvZ3Jlc3NfYmFyJG5ldyh0b3RhbCA9IEIpDQpmb3IgKGkgaW4gRXhwZXJpbWVudCkgew0KICBwYiR0aWNrKCkNCiAgREZMaXN0W1tpXV0gPC0NCiAgICBlbXB0eURhdGEgJT4lIHNpbVNhbGVzREYoY3RybE1lYW4gKyBlZmZlY3RTaXplLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGREaXYsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0cmxNZWFuLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGREaXYsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbGVzX01fZmFjdG9yLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYWxlc19TRF9mYWN0b3IpDQp9DQoNCmV4cFNpbURhdGEgPC0gdGliYmxlKEV4cGVyaW1lbnQgPSBFeHBlcmltZW50LCBERiA9IERGTGlzdCkNCmBgYA0KDQojIyMjIyBBbmFseXNpcw0KDQpgYGB7ciBxMV9zY2VuYXJpbzJfYW5hbHlzaXN9DQoNCiMgZ2V0IHQtdGVzdCByZXN1bHQgZm9yIHNpbXVsYXRpb24NCnNpbURhdGFBbmFseXplZCA8LSBleHBTaW1EYXRhICU+JSBtdXRhdGUoUmVzdWx0ID0gbWFwKERGLCBhbmFseXplRGF0YSkpICU+JSB1bm5lc3Rfd2lkZXIoUmVzdWx0KQ0KDQpwcmludChwYXN0ZSgiUG93ZXIgd2l0aCBhbiBlZmZlY3RpdmUgc2l6ZSBvZiAiLCBlZmZlY3RTaXplLCAiIGFuZCBhIHNpZ25pZmljYW50IGxldmVsIG9mICIsIHNpZ0xldmVsLCIgOiAiLCBtZWFuKHNpbURhdGFBbmFseXplZCRwIDwgc2lnTGV2ZWwpKSkNCnByaW50KHBhc3RlKCJBdmVyYWdlIFAgdmFsdWU6ICIsIG1lYW4oc2ltRGF0YUFuYWx5emVkJHApKSkNCnN1bW1hcnkoc2ltRGF0YUFuYWx5emVkJGVmZmVjdCkNCnN1bW1hcnkoc2ltRGF0YUFuYWx5emVkJGxvd2VyX2NpKQ0Kc3VtbWFyeShzaW1EYXRhQW5hbHl6ZWQkdXBwZXJfY2kpDQpgYGANCg0KVGhlIHNpbXVsYXRpb24gcmVzdWx0IHNob3dzIGEgUC12YWx1ZSAoMC4wMjkyKSB0aGF0IGlzIGxlc3MgdGhhbiA1JSwgd2hpY2ggaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4gVGhlcmVmb3JlLCB3ZSB3aWxsIHJlamVjdCBvdXIgbnVsbCBoeXBvdGhlc2lzIHRoYXQgdGhlIGxhdW5jaCBvZiBOZXNjYWZlIGNvbmNlbnRyYXRlZCBjb2ZmZWUgcG9kcyB3aWxsIG5vdCBpbmNyZWFzZSBOZXNjYWZl4oCZcyBzYWxlcyBpbiB0aGUgQ2hpbmVzZSBtYXJrZXQuIFdlIGFjY2VwdCBvdXIgYWx0ZXJuYXRpdmUgaHlwb3RoZXNpcyB0aGF0IHRoZSBsYXVuY2ggb2YgTmVzY2FmZSBjb25jZW50cmF0ZWQgY29mZmVlIHBvZHMgd2lsbCBpbmNyZWFzZSBOZXNjYWZl4oCZcyBzYWxlcyBpbiB0aGUgQ2hpbmVzZSBtYXJrZXQuIEluIHRoaXMgc2NlbmFyaW8sIHdlIHdpbGwgcmVjb21tZW5kIGxhdW5jaGluZyB0aGUgTmVzY2FmZSBjb25jZW50cmF0ZWQgY29mZmVlIHBvZHMgaW4gdGhlIENoaW5lc2UgbWFya2V0IHNpbmNlIGl0IHdpbGwgaW5jcmVhc2UgTmVzY2FmZeKAmXMgc2FsZXMuDQoNCiMjIEFwcGVuZGl4IA0KDQohW0ZpZ3VyZSAxXShQaWN0dXJlMS5wbmcpDQoNCioqRmlndXJlIDE6KiogVG90YWwgY29mZmVlIGNvbnN1bXB0aW9uIHZvbHVtZSBpbiBDaGluYS4gKFVTREEgRm9yZWlnbiBBZ3JpY3VsdHVyYWwgU2VydmljZSwgSnVuZSAyMSwgMjAyMCkNCg0KIVtGaWd1cmUgMl0oUGljdHVyZTIucG5nKQ0KDQoqKkZpZ3VyZSAyOioqIFRvdGFsIGNvZmZlZSBwcm9kdWN0aW9uIHZvbHVtZSBpbiBDaGluYS4gKFVTREEgRm9yZWlnbiBBZ3JpY3VsdHVyYWwgU2VydmljZSwgSnVuZSAyMSwgMjAyMCkgDQoNCiMjIFJlZmVyZW5jZXMNCg0KKipNaW5naGFvIER1ICg1MCUpIEhhb2h1YSBMdSAoNTAlKSoqOiANCg0KYGBge3J9DQpSZWFkQmliKCJteS1wYXBlci5iaWIiLCBjaGVjayA9IEZBTFNFKSANCmBgYA0KDQoNCmBgYHtyfQ0Kc3RvcEltcGxpY2l0Q2x1c3RlcigpDQpgYGANCg==